Skip to content

Commit a45df79

Browse files
goldfirereantalsz
andauthored
Add a Module_strengthening extension (#142)
* Add Strengthen extension for module types * Use Pmty_alias, not Pmty_ident. * Antal's suggestions * Comment improvement Co-authored-by: Antal Spector-Zabusky <[email protected]> --------- Co-authored-by: Antal Spector-Zabusky <[email protected]>
1 parent 163c4b9 commit a45df79

File tree

10 files changed

+102
-20
lines changed

10 files changed

+102
-20
lines changed

ocamldoc/odoc_sig.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,7 +1521,7 @@ module Analyser =
15211521
and analyse_module_type_kind
15221522
?(erased = Name.Map.empty) env current_module_name module_type sig_module_type =
15231523
match Extensions.Module_type.of_ast module_type with
1524-
| Some _ -> .
1524+
| Some (Emty_strengthen _) -> failwith "strengthen not implemented yet"
15251525
| None ->
15261526
match module_type.Parsetree.pmty_desc with
15271527
Parsetree.Pmty_ident longident ->
@@ -1622,7 +1622,7 @@ module Analyser =
16221622
and analyse_module_kind
16231623
?(erased = Name.Map.empty) env current_module_name module_type sig_module_type =
16241624
match Extensions.Module_type.of_ast module_type with
1625-
| Some _ -> .
1625+
| Some (Emty_strengthen _) -> failwith "strengthen not implemented yet"
16261626
| None ->
16271627
match module_type.Parsetree.pmty_desc with
16281628
| Parsetree.Pmty_ident _longident ->

parsing/ast_iterator.ml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,11 @@ module MT = struct
304304
sub.attributes sub attrs;
305305
sub.extension sub x
306306
| Psig_attribute x -> sub.attribute sub x
307+
308+
let iter_extension sub : Extensions.Module_type.t -> _ = function
309+
| Emty_strengthen { mty; mod_id } ->
310+
iter sub mty;
311+
iter_loc sub mod_id
307312
end
308313

309314

@@ -597,6 +602,7 @@ let default_iterator =
597602
signature = (fun this l -> List.iter (this.signature_item this) l);
598603
signature_item = MT.iter_signature_item;
599604
module_type = MT.iter;
605+
module_type_extension = MT.iter_extension;
600606
with_constraint = MT.iter_with_constraint;
601607
class_declaration =
602608
(fun this -> CE.class_infos this (this.class_expr this));
@@ -657,9 +663,6 @@ let default_iterator =
657663
this.attributes this pmtd_attributes;
658664
);
659665

660-
module_type_extension = (fun _this emty -> match emty with
661-
| _ -> .);
662-
663666
module_binding =
664667
(fun this {pmb_name; pmb_expr; pmb_attributes; pmb_loc} ->
665668
iter_loc this pmb_name; this.module_expr this pmb_expr;

parsing/ast_mapper.ml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ module MT = struct
285285
| Some emty -> begin
286286
Extensions_parsing.Module_type.wrap_desc ~loc ~attrs @@
287287
match sub.module_type_extension sub emty with
288-
| _ -> .
288+
| Emty_strengthen smty -> Extensions.Strengthen.mty_of ~loc smty
289289
end
290290
| None ->
291291
match desc with
@@ -343,6 +343,13 @@ module MT = struct
343343
let attrs = sub.attributes sub attrs in
344344
extension ~loc ~attrs (sub.extension sub x)
345345
| Psig_attribute x -> attribute ~loc (sub.attribute sub x)
346+
347+
let map_extension sub :
348+
Extensions.Module_type.t -> Extensions.Module_type.t = function
349+
| Emty_strengthen { mty; mod_id } ->
350+
let mty = sub.module_type sub mty in
351+
let mod_id = map_loc sub mod_id in
352+
Emty_strengthen { mty; mod_id }
346353
end
347354

348355

@@ -667,6 +674,7 @@ let default_mapper =
667674
signature = (fun this l -> List.map (this.signature_item this) l);
668675
signature_item = MT.map_signature_item;
669676
module_type = MT.map;
677+
module_type_extension = MT.map_extension;
670678
with_constraint = MT.map_with_constraint;
671679
class_declaration =
672680
(fun this -> CE.class_infos this (this.class_expr this));
@@ -730,9 +738,6 @@ let default_mapper =
730738
~loc:(this.location this pmtd_loc)
731739
);
732740

733-
module_type_extension =
734-
(fun _this emty -> match emty with _ -> .);
735-
736741
module_binding =
737742
(fun this {pmb_name; pmb_expr; pmb_attributes; pmb_loc} ->
738743
Mb.mk (map_loc this pmb_name) (this.module_expr this pmb_expr)

parsing/depend.ml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ and add_binding_op bv bv' pbop =
341341

342342
and add_modtype bv mty =
343343
match Extensions.Module_type.of_ast mty with
344-
| Some _ -> .
344+
| Some emty -> add_modtype_extension bv emty
345345
| None ->
346346
match mty.pmty_desc with
347347
Pmty_ident l -> add bv l
@@ -373,6 +373,11 @@ and add_modtype bv mty =
373373
| Pmty_typeof m -> add_module_expr bv m
374374
| Pmty_extension e -> handle_extension e
375375

376+
and add_modtype_extension bv : Extensions.Module_type.t -> _ = function
377+
| Emty_strengthen { mty; mod_id } ->
378+
add_modtype bv mty;
379+
add_module_path bv mod_id
380+
376381
and add_module_alias bv l =
377382
(* If we are in delayed dependencies mode, we delay the dependencies
378383
induced by "Lident s" *)
@@ -386,7 +391,7 @@ and add_module_alias bv l =
386391

387392
and add_modtype_binding bv mty =
388393
match Extensions.Module_type.of_ast mty with
389-
| Some _ -> .
394+
| Some emty -> add_modtype_extension_binding bv emty
390395
| None ->
391396
match mty.pmty_desc with
392397
Pmty_alias l ->
@@ -398,6 +403,13 @@ and add_modtype_binding bv mty =
398403
| _ ->
399404
add_modtype bv mty; bound
400405

406+
and add_modtype_extension_binding bv : Extensions.Module_type.t -> _ = function
407+
| Emty_strengthen { mty; mod_id } ->
408+
(* treat like a [with] constraint *)
409+
add_modtype bv mty;
410+
add_module_path bv mod_id;
411+
bound
412+
401413
and add_signature bv sg =
402414
ignore (add_signature_binding bv sg)
403415

parsing/extensions.ml

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,30 @@ module Immutable_arrays = struct
296296

297297
let of_pat expr = match expr.ppat_desc with
298298
| Ppat_array elts -> Iapat_immutable_array elts
299-
| _ -> failwith "Malformed immutable array expression"
299+
| _ -> failwith "Malformed immutable array pattern"
300+
end
301+
302+
(** Module strengthening *)
303+
module Strengthen = struct
304+
type nonrec module_type =
305+
{ mty : Parsetree.module_type; mod_id : Longident.t Location.loc }
306+
307+
let extension_string = Language_extension.to_string Module_strengthening
308+
309+
(* Encoding: [S with M] becomes [functor (_ : S) -> (module M)], where
310+
the [(module M)] is a [Pmty_alias]. This isn't syntax we can write, but
311+
[(module M)] can be the inferred type for [M], so this should be fine. *)
312+
313+
let mty_of ~loc { mty; mod_id } =
314+
(* See Note [Wrapping with make_extension] *)
315+
Module_type.make_extension ~loc [extension_string] @@
316+
Ast_helper.Mty.functor_ (Named (Location.mknoloc None, mty))
317+
(Ast_helper.Mty.alias mod_id)
318+
319+
let of_mty mty = match mty.pmty_desc with
320+
| Pmty_functor(Named(_, mty), {pmty_desc = Pmty_alias mod_id}) ->
321+
{ mty; mod_id }
322+
| _ -> failwith "Malformed strengthened module type"
300323
end
301324

302325
(******************************************************************************)
@@ -350,9 +373,12 @@ module Module_type = struct
350373
module M = struct
351374
module AST = Extensions_parsing.Module_type
352375

353-
type t = |
376+
type t =
377+
| Emty_strengthen of Strengthen.module_type
354378

355-
let of_ast_internal (ext : Language_extension.t) _mty = match ext with
379+
let of_ast_internal (ext : Language_extension.t) mty = match ext with
380+
| Module_strengthening ->
381+
Some (Emty_strengthen (Strengthen.of_mty mty))
356382
| _ -> None
357383
end
358384

parsing/extensions.mli

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,17 @@ module Immutable_arrays : sig
7979
val pat_of : loc:Location.t -> pattern -> Parsetree.pattern_desc
8080
end
8181

82+
(** The ASTs for module type strengthening. *)
83+
module Strengthen : sig
84+
type module_type =
85+
{ mty : Parsetree.module_type; mod_id : Longident.t Location.loc }
86+
87+
val mty_of : loc:Location.t -> module_type -> Parsetree.module_type_desc
88+
end
89+
90+
(******************************************)
91+
(* General facility, which we export *)
92+
8293
(** The module type of language extension ASTs, instantiated once for each
8394
syntactic category. We tend to call the pattern-matching functions here
8495
with unusual indentation, not indenting the [None] branch further so as to
@@ -135,6 +146,9 @@ module type AST = sig
135146
val of_ast : ast -> t option
136147
end
137148

149+
(******************************************)
150+
(* Individual syntactic categories *)
151+
138152
(** Language extensions in expressions *)
139153
module Expression : sig
140154
type t =
@@ -154,7 +168,8 @@ end
154168

155169
(** Language extensions in module types *)
156170
module Module_type : sig
157-
type t = |
171+
type t =
172+
| Emty_strengthen of Strengthen.module_type
158173

159174
include AST with type t := t and type ast := Parsetree.module_type
160175
end

parsing/pprintast.ml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,7 @@ and module_type ctxt f x =
11191119
(attributes ctxt) x.pmty_attributes
11201120
end else
11211121
match Extensions.Module_type.of_ast x with
1122-
| Some _ -> .
1122+
| Some emty -> module_type_extension ctxt f emty
11231123
| None ->
11241124
match x.pmty_desc with
11251125
| Pmty_functor (Unit, mt2) ->
@@ -1140,6 +1140,12 @@ and module_type ctxt f x =
11401140
(list (with_constraint ctxt) ~sep:"@ and@ ") l
11411141
| _ -> module_type1 ctxt f x
11421142

1143+
and module_type_extension ctxt f : Extensions.Module_type.t -> _ = function
1144+
| Emty_strengthen { mty; mod_id } ->
1145+
pp f "@[<hov2>%a@ with@ %a@]"
1146+
(module_type1 ctxt) mty
1147+
longident_loc mod_id
1148+
11431149
and with_constraint ctxt f = function
11441150
| Pwith_type (li, ({ptype_params= ls ;_} as td)) ->
11451151
let ls = List.map fst ls in
@@ -1165,7 +1171,7 @@ and with_constraint ctxt f = function
11651171
and module_type1 ctxt f x =
11661172
if x.pmty_attributes <> [] then module_type ctxt f x
11671173
else match Extensions.Module_type.of_ast x with
1168-
| Some _ -> .
1174+
| Some emty -> module_type_extension1 ctxt f emty
11691175
| None ->
11701176
match x.pmty_desc with
11711177
| Pmty_ident li ->
@@ -1180,6 +1186,9 @@ and module_type1 ctxt f x =
11801186
| Pmty_extension e -> extension ctxt f e
11811187
| _ -> paren true (module_type ctxt) f x
11821188

1189+
and module_type_extension1 ctxt f : Extensions.Module_type.t -> _ = function
1190+
| Emty_strengthen _ as emty -> paren true (module_type_extension ctxt) f emty
1191+
11831192
and signature ctxt f x = list ~sep:"@\n" (signature_item ctxt) f x
11841193

11851194
and signature_item ctxt f x : unit =

typing/typemod.ml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@ let map_ext fn exts =
835835

836836
let rec approx_modtype env smty =
837837
match Extensions.Module_type.of_ast smty with
838-
| Some _ -> .
838+
| Some emty -> approx_modtype_extension env emty
839839
| None ->
840840
match smty.pmty_desc with
841841
Pmty_ident lid ->
@@ -894,6 +894,9 @@ let rec approx_modtype env smty =
894894
| Pmty_extension ext ->
895895
raise (Error_forward (Builtin_attributes.error_of_extension ext))
896896

897+
and approx_modtype_extension _env : Extensions.Module_type.t -> _ = function
898+
| Emty_strengthen { mty=_; mod_id=_ } -> failwith "strengthen not yet implemented"
899+
897900
and approx_module_declaration env pmd =
898901
{
899902
Types.md_type = approx_modtype env pmd.pmd_type;
@@ -1373,7 +1376,7 @@ and transl_modtype_functor_arg env sarg =
13731376
and transl_modtype_aux env smty =
13741377
let loc = smty.pmty_loc in
13751378
match Extensions.Module_type.of_ast smty with
1376-
| Some _ -> .
1379+
| Some emty -> transl_modtype_extension_aux env emty
13771380
| None ->
13781381
match smty.pmty_desc with
13791382
Pmty_ident lid ->
@@ -1436,6 +1439,9 @@ and transl_modtype_aux env smty =
14361439
| Pmty_extension ext ->
14371440
raise (Error_forward (Builtin_attributes.error_of_extension ext))
14381441

1442+
and transl_modtype_extension_aux _env : Extensions.Module_type.t -> _ = function
1443+
| Emty_strengthen { mty=_ ; mod_id=_ } -> failwith "Strengthen not yet implemented"
1444+
14391445
and transl_with ~loc env remove_aliases (rev_tcstrs,sg) constr =
14401446
let lid, with_info = match constr with
14411447
| Pwith_type (l,decl) ->l , With_type decl

utils/language_extension.ml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ type t =
44
| Include_functor
55
| Polymorphic_parameters
66
| Immutable_arrays
7+
| Module_strengthening
78

89
let equal (a : t) (b : t) = (a = b)
910

@@ -13,6 +14,7 @@ let all =
1314
; Include_functor
1415
; Polymorphic_parameters
1516
; Immutable_arrays
17+
; Module_strengthening
1618
]
1719

1820
let default_extensions =
@@ -27,13 +29,15 @@ let to_string = function
2729
| Include_functor -> "include_functor"
2830
| Polymorphic_parameters -> "polymorphic_parameters"
2931
| Immutable_arrays -> "immutable_arrays_experimental"
32+
| Module_strengthening -> "module_strengthening"
3033

3134
let of_string extn = match String.lowercase_ascii extn with
3235
| "comprehensions_experimental" -> Some Comprehensions
3336
| "local" -> Some Local
3437
| "include_functor" -> Some Include_functor
3538
| "polymorphic_parameters" -> Some Polymorphic_parameters
3639
| "immutable_arrays_experimental" -> Some Immutable_arrays
40+
| "strengthening" -> Some Module_strengthening
3741
| _ -> None
3842

3943
let of_string_exn extn =
@@ -48,7 +52,8 @@ let is_erasable = function
4852
| Comprehensions
4953
| Include_functor
5054
| Polymorphic_parameters
51-
| Immutable_arrays ->
55+
| Immutable_arrays
56+
| Module_strengthening ->
5257
false
5358

5459
module Universe = struct

utils/language_extension.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ type t =
77
| Include_functor
88
| Polymorphic_parameters
99
| Immutable_arrays
10+
| Module_strengthening
1011

1112
(** Equality on language extensions *)
1213
val equal : t -> t -> bool

0 commit comments

Comments
 (0)