Skip to content

Commit cea684f

Browse files
author
Nathan Rebours
committed
TMP: Wrap encoded external types in extensions
Signed-off-by: Nathan Rebours <nathan.rebours@ocamlpro.com>
1 parent cf276a1 commit cea684f

File tree

6 files changed

+222
-54
lines changed

6 files changed

+222
-54
lines changed

astlib/encoding_505.ml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ module Ext_name = struct
55
let ptyp_functor = "ppxlib.migration.ptyp_functor_5_5"
66
let preserve_ppat_constraint = "ppxlib.migration.preserve_ppat_constraint_5_5"
77
let ptype_kind_external = "ppxlib.migration.ptype_kind_external_5_5"
8+
let external_psig = "ppxlib.migration.external_psig_5_5"
9+
let external_pstr_type = "ppxlib.migration.external_pstr_type_5_5"
10+
let external_pmty_with = "ppxlib.migration.external_pmty_with_5_5"
811
end
912

1013
let invalid_encoding ~loc name =
@@ -104,6 +107,52 @@ module To_504 = struct
104107
Some (name, ptype_attributes)
105108
| _ -> None
106109

110+
let encode_external_psig ~loc psig_desc =
111+
112+
let loc = { loc with Location.loc_ghost = true } in
113+
let ext =
114+
( {txt = Ext_name.external_psig; loc},
115+
PSig [ {psig_loc = loc; psig_desc} ] )
116+
in
117+
Psig_extension (ext, [])
118+
119+
let encode_external_psig_type ~loc rec_flag tds =
120+
encode_external_psig ~loc (Psig_type (rec_flag, tds))
121+
122+
let encode_external_psig_typesubst ~loc tds =
123+
encode_external_psig ~loc (Psig_typesubst tds)
124+
125+
let encode_external_pstr_type ~loc rec_flag tds =
126+
let loc = { loc with Location.loc_ghost = true } in
127+
let pstr_desc = Pstr_type (rec_flag, tds) in
128+
let ext =
129+
( {txt = Ext_name.external_psig; loc},
130+
PStr [ {pstr_loc = loc; pstr_desc} ] )
131+
in
132+
Pstr_extension (ext, [])
133+
134+
let encode_external_pmty_with ~loc mty constraints =
135+
let loc = { loc with Location.loc_ghost = true } in
136+
let pmd_type =
137+
{ pmty_loc = loc
138+
; pmty_attributes = []
139+
; pmty_desc = Pmty_with (mty, constraints)
140+
}
141+
in
142+
let psig_desc =
143+
Psig_module
144+
{ pmd_name = {txt = None; loc}
145+
; pmd_type
146+
; pmd_attributes = []
147+
; pmd_loc = loc
148+
}
149+
in
150+
let ext =
151+
( {txt = Ext_name.external_psig; loc},
152+
PSig [ {psig_loc = loc; psig_desc} ] )
153+
in
154+
Pmty_extension ext
155+
107156
let must_preserve_ppat_constraint l =
108157
List.without_first l ~pred:(fun attr ->
109158
String.equal attr.attr_name.txt Ext_name.preserve_ppat_constraint)

astlib/encoding_505.mli

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ module Ext_name : sig
33
val ptyp_functor : string
44
val preserve_ppat_constraint : string
55
val ptype_kind_external : string
6+
val external_psig : string
7+
val external_pstr_type : string
8+
val external_pmty_with : string
69
end
710

811
module To_504 : sig
@@ -31,6 +34,18 @@ module To_504 : sig
3134
val decode_ptype_kind_external :
3235
type_declaration -> (string * attributes) option
3336

37+
val encode_external_psig_type :
38+
loc:Location.t -> rec_flag -> type_declaration list -> signature_item_desc
39+
40+
val encode_external_psig_typesubst :
41+
loc:Location.t -> type_declaration list -> signature_item_desc
42+
43+
val encode_external_pstr_type :
44+
loc:Location.t -> rec_flag -> type_declaration list -> structure_item_desc
45+
46+
val encode_external_pmty_with :
47+
loc:Location.t -> module_type -> with_constraint list -> module_type_desc
48+
3449
val must_preserve_ppat_constraint : attributes -> attributes option
3550
(** Returns [None] if the list does not contain
3651
[@ppxlib.migration.preserve_ppat_constraint_505] or [Some l] where [l] is

astlib/migrate_505_504.ml

Lines changed: 135 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ module From = Ast_505
33
module To = Ast_504
44

55
module External_type = struct
6-
type exn += T of string
6+
type exn +=
7+
| T of string
8+
| Type_decl of Ast_504.Parsetree.type_declaration
9+
| With_constr of Ast_504.Parsetree.with_constraint
710
end
811

912
let copy_location x = x
@@ -617,35 +620,52 @@ and copy_type_declaration :
617620
Ast_505.Parsetree.ptype_loc;
618621
} ->
619622
let loc = copy_location ptype_loc in
620-
let ptype_kind, ptype_attributes =
623+
let is_external, (ptype_kind, ptype_attributes) =
621624
let attributes = copy_attributes ptype_attributes in
622625
match copy_type_kind ptype_kind with
623-
| ptype_kind -> (ptype_kind, attributes)
626+
| ptype_kind -> false, (ptype_kind, attributes)
624627
| exception External_type.T name ->
625-
Encoding_505.To_504.encode_ptype_kind_external ~loc name attributes
628+
true, Encoding_505.To_504.encode_ptype_kind_external ~loc name attributes
626629
in
627-
{
628-
Ast_504.Parsetree.ptype_name = copy_loc (fun x -> x) ptype_name;
629-
Ast_504.Parsetree.ptype_params =
630-
List.map
631-
(fun x ->
632-
let x0, x1 = x in
633-
( copy_core_type x0,
634-
let x0, x1 = x1 in
635-
(copy_variance x0, copy_injectivity x1) ))
636-
ptype_params;
637-
Ast_504.Parsetree.ptype_cstrs =
638-
List.map
639-
(fun x ->
640-
let x0, x1, x2 = x in
641-
(copy_core_type x0, copy_core_type x1, copy_location x2))
642-
ptype_constraints;
643-
Ast_504.Parsetree.ptype_kind;
644-
Ast_504.Parsetree.ptype_private = copy_private_flag ptype_private;
645-
Ast_504.Parsetree.ptype_manifest = Option.map copy_core_type ptype_manifest;
646-
Ast_504.Parsetree.ptype_attributes;
647-
Ast_504.Parsetree.ptype_loc = loc;
648-
}
630+
let td =
631+
{
632+
Ast_504.Parsetree.ptype_name = copy_loc (fun x -> x) ptype_name;
633+
Ast_504.Parsetree.ptype_params =
634+
List.map
635+
(fun x ->
636+
let x0, x1 = x in
637+
( copy_core_type x0,
638+
let x0, x1 = x1 in
639+
(copy_variance x0, copy_injectivity x1) ))
640+
ptype_params;
641+
Ast_504.Parsetree.ptype_cstrs =
642+
List.map
643+
(fun x ->
644+
let x0, x1, x2 = x in
645+
(copy_core_type x0, copy_core_type x1, copy_location x2))
646+
ptype_constraints;
647+
Ast_504.Parsetree.ptype_kind;
648+
Ast_504.Parsetree.ptype_private = copy_private_flag ptype_private;
649+
Ast_504.Parsetree.ptype_manifest = Option.map copy_core_type ptype_manifest;
650+
Ast_504.Parsetree.ptype_attributes;
651+
Ast_504.Parsetree.ptype_loc = loc;
652+
}
653+
in
654+
if is_external then raise (External_type.Type_decl td) else td
655+
656+
and copy_type_declaration_list l =
657+
let contains_external = ref false in
658+
let tds =
659+
List.map
660+
(fun td ->
661+
match copy_type_declaration td with
662+
| td' -> td'
663+
| exception External_type.Type_decl td' ->
664+
contains_external := true;
665+
td')
666+
l
667+
in
668+
tds, !contains_external
649669

650670
and copy_type_kind : Ast_505.Parsetree.type_kind -> Ast_504.Parsetree.type_kind
651671
= function
@@ -999,13 +1019,14 @@ and copy_module_type :
9991019
Ast_505.Parsetree.pmty_loc;
10001020
Ast_505.Parsetree.pmty_attributes;
10011021
} ->
1022+
let loc = copy_location pmty_loc in
10021023
{
1003-
Ast_504.Parsetree.pmty_desc = copy_module_type_desc pmty_desc;
1004-
Ast_504.Parsetree.pmty_loc = copy_location pmty_loc;
1024+
Ast_504.Parsetree.pmty_desc = copy_module_type_desc_with_loc ~loc pmty_desc;
1025+
Ast_504.Parsetree.pmty_loc = loc;
10051026
Ast_504.Parsetree.pmty_attributes = copy_attributes pmty_attributes;
10061027
}
10071028

1008-
and copy_module_type_desc :
1029+
and copy_module_type_desc_with_loc ~loc :
10091030
Ast_505.Parsetree.module_type_desc -> Ast_504.Parsetree.module_type_desc =
10101031
function
10111032
| Ast_505.Parsetree.Pmty_ident x0 ->
@@ -1016,15 +1037,35 @@ and copy_module_type_desc :
10161037
Ast_504.Parsetree.Pmty_functor
10171038
(copy_functor_parameter x0, copy_module_type x1)
10181039
| Ast_505.Parsetree.Pmty_with (x0, x1) ->
1019-
Ast_504.Parsetree.Pmty_with
1020-
(copy_module_type x0, List.map copy_with_constraint x1)
1040+
let mty = copy_module_type x0 in
1041+
let constraints, contains_external =
1042+
let contains_external = ref false in
1043+
let constraints =
1044+
List.map
1045+
(fun c ->
1046+
match copy_with_constraint c with
1047+
| c' -> c'
1048+
| exception External_type.With_constr c' ->
1049+
contains_external := true;
1050+
c')
1051+
x1
1052+
in
1053+
constraints, !contains_external
1054+
in
1055+
if contains_external then
1056+
Encoding_505.To_504.encode_external_pmty_with ~loc mty constraints
1057+
else
1058+
Ast_504.Parsetree.Pmty_with (mty, constraints)
10211059
| Ast_505.Parsetree.Pmty_typeof x0 ->
10221060
Ast_504.Parsetree.Pmty_typeof (copy_module_expr x0)
10231061
| Ast_505.Parsetree.Pmty_extension x0 ->
10241062
Ast_504.Parsetree.Pmty_extension (copy_extension x0)
10251063
| Ast_505.Parsetree.Pmty_alias x0 ->
10261064
Ast_504.Parsetree.Pmty_alias (copy_loc copy_longident x0)
10271065

1066+
and copy_module_type_desc mty_desc =
1067+
copy_module_type_desc_with_loc ~loc:Location.none mty_desc
1068+
10281069
and copy_functor_parameter :
10291070
Ast_505.Parsetree.functor_parameter -> Ast_504.Parsetree.functor_parameter =
10301071
function
@@ -1040,21 +1081,31 @@ and copy_signature : Ast_505.Parsetree.signature -> Ast_504.Parsetree.signature
10401081
and copy_signature_item :
10411082
Ast_505.Parsetree.signature_item -> Ast_504.Parsetree.signature_item =
10421083
fun { Ast_505.Parsetree.psig_desc; Ast_505.Parsetree.psig_loc } ->
1084+
let loc = copy_location psig_loc in
10431085
{
1044-
Ast_504.Parsetree.psig_desc = copy_signature_item_desc psig_desc;
1045-
Ast_504.Parsetree.psig_loc = copy_location psig_loc;
1086+
Ast_504.Parsetree.psig_desc =
1087+
copy_signature_item_desc_with_loc ~loc psig_desc;
1088+
Ast_504.Parsetree.psig_loc = loc;
10461089
}
10471090

1048-
and copy_signature_item_desc :
1091+
and copy_signature_item_desc_with_loc ~loc :
10491092
Ast_505.Parsetree.signature_item_desc ->
10501093
Ast_504.Parsetree.signature_item_desc = function
10511094
| Ast_505.Parsetree.Psig_value x0 ->
10521095
Ast_504.Parsetree.Psig_value (copy_value_description x0)
10531096
| Ast_505.Parsetree.Psig_type (x0, x1) ->
1054-
Ast_504.Parsetree.Psig_type
1055-
(copy_rec_flag x0, List.map copy_type_declaration x1)
1097+
let rec_flag = copy_rec_flag x0 in
1098+
let tds, contains_external = copy_type_declaration_list x1 in
1099+
if contains_external then
1100+
Encoding_505.To_504.encode_external_psig_type ~loc rec_flag tds
1101+
else
1102+
Ast_504.Parsetree.Psig_type (rec_flag, tds)
10561103
| Ast_505.Parsetree.Psig_typesubst x0 ->
1057-
Ast_504.Parsetree.Psig_typesubst (List.map copy_type_declaration x0)
1104+
let tds, contains_external = copy_type_declaration_list x0 in
1105+
if contains_external then
1106+
Encoding_505.To_504.encode_external_psig_typesubst ~loc tds
1107+
else
1108+
Ast_504.Parsetree.Psig_typesubst tds
10581109
| Ast_505.Parsetree.Psig_typext x0 ->
10591110
Ast_504.Parsetree.Psig_typext (copy_type_extension x0)
10601111
| Ast_505.Parsetree.Psig_exception x0 ->
@@ -1083,6 +1134,9 @@ and copy_signature_item_desc :
10831134
| Ast_505.Parsetree.Psig_extension (x0, x1) ->
10841135
Ast_504.Parsetree.Psig_extension (copy_extension x0, copy_attributes x1)
10851136

1137+
and copy_signature_item_desc sigi_desc =
1138+
copy_signature_item_desc_with_loc ~loc:Location.none sigi_desc
1139+
10861140
and copy_module_declaration :
10871141
Ast_505.Parsetree.module_declaration -> Ast_504.Parsetree.module_declaration
10881142
=
@@ -1189,23 +1243,41 @@ and copy_with_constraint :
11891243
Ast_505.Parsetree.with_constraint -> Ast_504.Parsetree.with_constraint =
11901244
function
11911245
| Ast_505.Parsetree.Pwith_type (x0, x1) ->
1192-
Ast_504.Parsetree.Pwith_type
1193-
(copy_loc copy_longident x0, copy_type_declaration x1)
1246+
let lident_loc = copy_loc copy_longident x0 in
1247+
let td, is_external =
1248+
match copy_type_declaration x1 with
1249+
| td -> td, false
1250+
| exception External_type.Type_decl td -> td, true
1251+
in
1252+
let constr = Ast_504.Parsetree.Pwith_type (lident_loc, td) in
1253+
if is_external then
1254+
raise (External_type.With_constr constr)
1255+
else
1256+
constr
11941257
| Ast_505.Parsetree.Pwith_module (x0, x1) ->
1195-
Ast_504.Parsetree.Pwith_module
1196-
(copy_loc copy_longident x0, copy_loc copy_longident x1)
1258+
Ast_504.Parsetree.Pwith_module
1259+
(copy_loc copy_longident x0, copy_loc copy_longident x1)
11971260
| Ast_505.Parsetree.Pwith_modtype (x0, x1) ->
1198-
Ast_504.Parsetree.Pwith_modtype
1199-
(copy_loc copy_longident x0, copy_module_type x1)
1261+
Ast_504.Parsetree.Pwith_modtype
1262+
(copy_loc copy_longident x0, copy_module_type x1)
12001263
| Ast_505.Parsetree.Pwith_modtypesubst (x0, x1) ->
1201-
Ast_504.Parsetree.Pwith_modtypesubst
1202-
(copy_loc copy_longident x0, copy_module_type x1)
1264+
Ast_504.Parsetree.Pwith_modtypesubst
1265+
(copy_loc copy_longident x0, copy_module_type x1)
12031266
| Ast_505.Parsetree.Pwith_typesubst (x0, x1) ->
1204-
Ast_504.Parsetree.Pwith_typesubst
1205-
(copy_loc copy_longident x0, copy_type_declaration x1)
1267+
let lident_loc = copy_loc copy_longident x0 in
1268+
let td, is_external =
1269+
match copy_type_declaration x1 with
1270+
| td -> td, false
1271+
| exception External_type.Type_decl td -> td, true
1272+
in
1273+
let constr = Ast_504.Parsetree.Pwith_typesubst (lident_loc, td) in
1274+
if is_external then
1275+
raise (External_type.With_constr constr)
1276+
else
1277+
constr
12061278
| Ast_505.Parsetree.Pwith_modsubst (x0, x1) ->
1207-
Ast_504.Parsetree.Pwith_modsubst
1208-
(copy_loc copy_longident x0, copy_loc copy_longident x1)
1279+
Ast_504.Parsetree.Pwith_modsubst
1280+
(copy_loc copy_longident x0, copy_loc copy_longident x1)
12091281

12101282
and copy_module_expr :
12111283
Ast_505.Parsetree.module_expr -> Ast_504.Parsetree.module_expr =
@@ -1249,12 +1321,14 @@ and copy_structure : Ast_505.Parsetree.structure -> Ast_504.Parsetree.structure
12491321
and copy_structure_item :
12501322
Ast_505.Parsetree.structure_item -> Ast_504.Parsetree.structure_item =
12511323
fun { Ast_505.Parsetree.pstr_desc; Ast_505.Parsetree.pstr_loc } ->
1324+
let loc = copy_location pstr_loc in
12521325
{
1253-
Ast_504.Parsetree.pstr_desc = copy_structure_item_desc pstr_desc;
1254-
Ast_504.Parsetree.pstr_loc = copy_location pstr_loc;
1326+
Ast_504.Parsetree.pstr_desc =
1327+
copy_structure_item_desc_with_loc ~loc pstr_desc;
1328+
Ast_504.Parsetree.pstr_loc = loc;
12551329
}
12561330

1257-
and copy_structure_item_desc :
1331+
and copy_structure_item_desc_with_loc ~loc :
12581332
Ast_505.Parsetree.structure_item_desc ->
12591333
Ast_504.Parsetree.structure_item_desc = function
12601334
| Ast_505.Parsetree.Pstr_eval (x0, x1) ->
@@ -1265,8 +1339,12 @@ and copy_structure_item_desc :
12651339
| Ast_505.Parsetree.Pstr_primitive x0 ->
12661340
Ast_504.Parsetree.Pstr_primitive (copy_value_description x0)
12671341
| Ast_505.Parsetree.Pstr_type (x0, x1) ->
1268-
Ast_504.Parsetree.Pstr_type
1269-
(copy_rec_flag x0, List.map copy_type_declaration x1)
1342+
let rec_flag = copy_rec_flag x0 in
1343+
let tds, contains_external = copy_type_declaration_list x1 in
1344+
if contains_external then
1345+
Encoding_505.To_504.encode_external_pstr_type ~loc rec_flag tds
1346+
else
1347+
Ast_504.Parsetree.Pstr_type (rec_flag, tds)
12701348
| Ast_505.Parsetree.Pstr_typext x0 ->
12711349
Ast_504.Parsetree.Pstr_typext (copy_type_extension x0)
12721350
| Ast_505.Parsetree.Pstr_exception x0 ->
@@ -1291,6 +1369,9 @@ and copy_structure_item_desc :
12911369
| Ast_505.Parsetree.Pstr_extension (x0, x1) ->
12921370
Ast_504.Parsetree.Pstr_extension (copy_extension x0, copy_attributes x1)
12931371

1372+
and copy_structure_item_desc stri_desc =
1373+
copy_structure_item_desc_with_loc ~loc:Location.none stri_desc
1374+
12941375
and copy_value_constraint :
12951376
Ast_505.Parsetree.value_constraint -> Ast_504.Parsetree.value_constraint =
12961377
function

test/encoding/5.5/migrations/dune

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
(executable
2+
(name id_driver)
3+
(modules id_driver)
4+
(libraries ppxlib))
5+
6+
(cram
7+
(package ppxlib)
8+
(enabled_if
9+
(>= %{ocaml_version} 5.5))
10+
(deps id_driver.exe))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
let () = Ppxlib.Driver.standalone ()

0 commit comments

Comments
 (0)