Skip to content

Commit e90b23c

Browse files
author
Nathan Rebours
committed
Swap default Ppat_unpack migration
Signed-off-by: Nathan Rebours <nathan.rebours@ocamlpro.com>
1 parent 265e7a2 commit e90b23c

File tree

4 files changed

+85
-25
lines changed

4 files changed

+85
-25
lines changed

astlib/encoding_505.ml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module Ext_name = struct
22
let pexp_struct_item = "ppxlib.migration.pexp_struct_item_505"
33
let ptyp_functor = "ppxlib.migration.ptyp_functor_505"
4-
let ppat_unpack = "ppxlib.migration.ppat_unpack_505"
4+
let preserve_ppat_constraint = "ppxlib.migration.preserve_ppat_constraint_505"
55
let ptype_kind_external = "ppxlib.migration.ptype_kind_external_505"
66
end
77

@@ -90,4 +90,27 @@ module To_504 = struct
9090
when String.equal txt Ext_name.ptype_kind_external ->
9191
Some name
9292
| _ -> None
93+
94+
let must_preserve_ppat_constraint l =
95+
let rec aux seen = function
96+
| [] -> None
97+
| { attr_name = { txt; _ }; _ } :: tl
98+
when String.equal txt Ext_name.preserve_ppat_constraint ->
99+
Some (List.rev_append seen tl)
100+
| hd :: tl -> aux (hd :: seen) tl
101+
in
102+
aux [] l
103+
104+
let preserve_ppat_constraint pattern core_type =
105+
let loc = pattern.ppat_loc in
106+
let flag =
107+
{
108+
attr_name = { txt = Ext_name.preserve_ppat_constraint; loc };
109+
attr_payload = PStr [];
110+
attr_loc = loc;
111+
}
112+
in
113+
Ppat_constraint
114+
( { pattern with ppat_attributes = flag :: pattern.ppat_attributes },
115+
core_type )
93116
end

astlib/encoding_505.mli

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module Ext_name : sig
2+
val pexp_struct_item : string
3+
val ptyp_functor : string
4+
val preserve_ppat_constraint : string
5+
val ptype_kind_external : string
6+
end
7+
8+
module To_504 : sig
9+
open Ast_504.Asttypes
10+
open Ast_504.Parsetree
11+
12+
val encode_pexp_struct_item :
13+
loc:Location.t -> structure_item * expression -> expression_desc
14+
15+
val decode_pexp_struct_item :
16+
loc:Location.t -> payload -> structure_item * expression
17+
18+
val encode_ptyp_functor :
19+
loc:Location.t ->
20+
arg_label * string loc * package_type * core_type ->
21+
core_type_desc
22+
23+
val decode_ptyp_functor :
24+
loc:Location.t ->
25+
payload ->
26+
arg_label * string loc * package_type * core_type
27+
28+
val encode_ptype_kind_external : string -> attribute
29+
val decode_ptype_kind_external : attribute -> string option
30+
31+
val must_preserve_ppat_constraint : attributes -> attributes option
32+
(** Returns [None] if the list does not contain
33+
[@ppxlib.migration.preserve_ppat_constraint_505] or [Some l] where [l] is
34+
the remainder of the attributes. Should be used to determine whether a
35+
[Ppat_constraint (Ppat_unpack m, Ptyp_package s)] node should be preserved
36+
when migrated to 5.5 or turned into [Ppat_unpack (m, Some s)]. The
37+
attribute should be attached to the [Ppat_unpack] node within the
38+
[Ppat_constraint]. *)
39+
40+
val preserve_ppat_constraint : pattern -> core_type -> pattern_desc
41+
end

astlib/migrate_504_505.ml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -330,13 +330,14 @@ and copy_pattern_desc :
330330
| Ast_504.Parsetree.Ppat_constraint
331331
( ({ ppat_desc = Ppat_unpack p; ppat_attributes; _ } as x0),
332332
({ ptyp_desc = Ptyp_package pkg; _ } as x1) ) -> (
333-
match ppat_attributes with
334-
| [ { attr_name = { txt; _ } } ]
335-
when String.equal txt Encoding_505.Ext_name.ppat_unpack ->
336-
Ast_505.Parsetree.Ppat_unpack (p, Some (copy_package_type pkg))
337-
| _ ->
338-
Ast_505.Parsetree.Ppat_constraint (copy_pattern x0, copy_core_type x1)
339-
)
333+
let preserve =
334+
Encoding_505.To_504.must_preserve_ppat_constraint ppat_attributes
335+
in
336+
match preserve with
337+
| None -> Ast_505.Parsetree.Ppat_unpack (p, Some (copy_package_type pkg))
338+
| Some ppat_attributes ->
339+
Ast_505.Parsetree.Ppat_constraint
340+
(copy_pattern { x0 with ppat_attributes }, copy_core_type x1))
340341
| Ast_504.Parsetree.Ppat_constraint (x0, x1) ->
341342
Ast_505.Parsetree.Ppat_constraint (copy_pattern x0, copy_core_type x1)
342343
| Ast_504.Parsetree.Ppat_type x0 ->

astlib/migrate_505_504.ml

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,13 @@ and copy_pattern : Ast_505.Parsetree.pattern -> Ast_504.Parsetree.pattern =
276276
Ast_505.Parsetree.ppat_attributes;
277277
} ->
278278
{
279-
Ast_504.Parsetree.ppat_desc = copy_pattern_desc ppat_desc;
279+
Ast_504.Parsetree.ppat_desc = copy_pattern_desc ~loc:ppat_loc ppat_desc;
280280
Ast_504.Parsetree.ppat_loc = copy_location ppat_loc;
281281
Ast_504.Parsetree.ppat_loc_stack = copy_location_stack ppat_loc_stack;
282282
Ast_504.Parsetree.ppat_attributes = copy_attributes ppat_attributes;
283283
}
284284

285-
and copy_pattern_desc :
285+
and copy_pattern_desc ~loc :
286286
Ast_505.Parsetree.pattern_desc -> Ast_504.Parsetree.pattern_desc = function
287287
| Ast_505.Parsetree.Ppat_any -> Ast_504.Parsetree.Ppat_any
288288
| Ast_505.Parsetree.Ppat_var x0 ->
@@ -323,6 +323,12 @@ and copy_pattern_desc :
323323
Ast_504.Parsetree.Ppat_array (List.map copy_pattern x0)
324324
| Ast_505.Parsetree.Ppat_or (x0, x1) ->
325325
Ast_504.Parsetree.Ppat_or (copy_pattern x0, copy_pattern x1)
326+
| Ast_505.Parsetree.Ppat_constraint
327+
( ({ ppat_desc = Ppat_unpack (_, None); _ } as x0),
328+
({ ptyp_desc = Ptyp_package _; _ } as x1) ) ->
329+
let x0' = copy_pattern x0 in
330+
let x1' = copy_core_type x1 in
331+
Encoding_505.To_504.preserve_ppat_constraint x0' x1'
326332
| Ast_505.Parsetree.Ppat_constraint (x0, x1) ->
327333
Ast_504.Parsetree.Ppat_constraint (copy_pattern x0, copy_core_type x1)
328334
| Ast_505.Parsetree.Ppat_type x0 ->
@@ -336,30 +342,19 @@ and copy_pattern_desc :
336342
match x1 with
337343
| None -> unpack
338344
| Some c ->
339-
let ghost_loc loc = { loc with Location.loc_ghost = true } in
340-
let flag_attr : Ast_504.Parsetree.attribute =
341-
{
342-
attr_name =
343-
{
344-
txt = Encoding_505.Ext_name.ppat_unpack;
345-
loc = ghost_loc Location.none;
346-
};
347-
attr_loc = ghost_loc Location.none;
348-
attr_payload = PStr [];
349-
}
350-
in
345+
let ghost_loc = { loc with Location.loc_ghost = true } in
351346
let unpack_pattern : Ast_504.Parsetree.pattern =
352347
{
353348
ppat_desc = unpack;
354-
ppat_loc = ghost_loc Location.none;
355-
ppat_attributes = [ flag_attr ];
349+
ppat_loc = ghost_loc;
350+
ppat_attributes = [];
356351
ppat_loc_stack = [];
357352
}
358353
in
359354
let package_type : Ast_504.Parsetree.core_type =
360355
{
361356
ptyp_desc = Ptyp_package (copy_package_type c);
362-
ptyp_loc = ghost_loc Location.none;
357+
ptyp_loc = ghost_loc;
363358
ptyp_attributes = [];
364359
ptyp_loc_stack = [];
365360
}

0 commit comments

Comments
 (0)