Skip to content

Commit 37d0d90

Browse files
committed
pass record field expr as optional
1 parent 724caca commit 37d0d90

File tree

9 files changed

+83
-24
lines changed

9 files changed

+83
-24
lines changed

compiler/ml/ast_iterator.ml

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ type iterator = {
4444
open_description: iterator -> open_description -> unit;
4545
pat: iterator -> pattern -> unit;
4646
payload: iterator -> payload -> unit;
47+
record_field: iterator -> expression record_element -> unit;
48+
record_field_pat: iterator -> pattern record_element -> unit;
4749
signature: iterator -> signature -> unit;
4850
signature_item: iterator -> signature_item -> unit;
4951
structure: iterator -> structure -> unit;
@@ -309,11 +311,7 @@ module E = struct
309311
iter_opt (sub.expr sub) arg
310312
| Pexp_variant (_lab, eo) -> iter_opt (sub.expr sub) eo
311313
| Pexp_record (l, eo) ->
312-
List.iter
313-
(fun {lid; x = exp} ->
314-
iter_loc sub lid;
315-
sub.expr sub exp)
316-
l;
314+
List.iter (sub.record_field sub) l;
317315
iter_opt (sub.expr sub) eo
318316
| Pexp_field (e, lid) ->
319317
sub.expr sub e;
@@ -399,12 +397,7 @@ module P = struct
399397
iter_loc sub l;
400398
iter_opt (sub.pat sub) p
401399
| Ppat_variant (_l, p) -> iter_opt (sub.pat sub) p
402-
| Ppat_record (lpl, _cf) ->
403-
List.iter
404-
(fun {lid; x = pat} ->
405-
iter_loc sub lid;
406-
sub.pat sub pat)
407-
lpl
400+
| Ppat_record (lpl, _cf) -> List.iter (sub.record_field_pat sub) lpl
408401
| Ppat_array pl -> List.iter (sub.pat sub) pl
409402
| Ppat_or (p1, p2) ->
410403
sub.pat sub p1;
@@ -528,4 +521,12 @@ let default_iterator =
528521
| PPat (x, g) ->
529522
this.pat this x;
530523
iter_opt (this.expr this) g);
524+
record_field =
525+
(fun this {lid; x; opt = _} ->
526+
iter_loc this lid;
527+
this.expr this x);
528+
record_field_pat =
529+
(fun this {lid; x; opt = _} ->
530+
iter_loc this lid;
531+
this.pat this x);
531532
}

compiler/ml/ast_iterator.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ type iterator = {
4242
open_description: iterator -> open_description -> unit;
4343
pat: iterator -> pattern -> unit;
4444
payload: iterator -> payload -> unit;
45+
record_field: iterator -> expression record_element -> unit;
46+
record_field_pat: iterator -> pattern record_element -> unit;
4547
signature: iterator -> signature -> unit;
4648
signature_item: iterator -> signature_item -> unit;
4749
structure: iterator -> structure -> unit;

compiler/ml/ast_mapper.ml

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ type mapper = {
4848
open_description: mapper -> open_description -> open_description;
4949
pat: mapper -> pattern -> pattern;
5050
payload: mapper -> payload -> payload;
51+
record_field:
52+
mapper -> expression record_element -> expression record_element;
53+
record_field_pat: mapper -> pattern record_element -> pattern record_element;
5154
signature: mapper -> signature -> signature;
5255
signature_item: mapper -> signature_item -> signature_item;
5356
structure: mapper -> structure -> structure;
@@ -305,10 +308,7 @@ module E = struct
305308
variant ~loc ~attrs lab (map_opt (sub.expr sub) eo)
306309
| Pexp_record (l, eo) ->
307310
record ~loc ~attrs
308-
(List.map
309-
(fun {lid; x = exp; opt} ->
310-
{lid = map_loc sub lid; x = sub.expr sub exp; opt})
311-
l)
311+
(List.map (sub.record_field sub) l)
312312
(map_opt (sub.expr sub) eo)
313313
| Pexp_field (e, lid) ->
314314
field ~loc ~attrs (sub.expr sub e) (map_loc sub lid)
@@ -391,12 +391,7 @@ module P = struct
391391
construct ~loc ~attrs (map_loc sub l) (map_opt (sub.pat sub) p)
392392
| Ppat_variant (l, p) -> variant ~loc ~attrs l (map_opt (sub.pat sub) p)
393393
| Ppat_record (lpl, cf) ->
394-
record ~loc ~attrs
395-
(List.map
396-
(fun {lid; x = pat; opt} ->
397-
{lid = map_loc sub lid; x = sub.pat sub pat; opt})
398-
lpl)
399-
cf
394+
record ~loc ~attrs (List.map (sub.record_field_pat sub) lpl) cf
400395
| Ppat_array pl -> array ~loc ~attrs (List.map (sub.pat sub) pl)
401396
| Ppat_or (p1, p2) -> or_ ~loc ~attrs (sub.pat sub p1) (sub.pat sub p2)
402397
| Ppat_constraint (p, t) ->
@@ -509,6 +504,12 @@ let default_mapper =
509504
| PSig x -> PSig (this.signature this x)
510505
| PTyp x -> PTyp (this.typ this x)
511506
| PPat (x, g) -> PPat (this.pat this x, map_opt (this.expr this) g));
507+
record_field =
508+
(fun this {lid; x; opt} ->
509+
{lid = map_loc this lid; x = this.expr this x; opt});
510+
record_field_pat =
511+
(fun this {lid; x; opt} ->
512+
{lid = map_loc this lid; x = this.pat this x; opt});
512513
}
513514

514515
let rec extension_of_error {loc; msg; if_highlight; sub} =

compiler/ml/ast_mapper.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ type mapper = {
7676
open_description: mapper -> open_description -> open_description;
7777
pat: mapper -> pattern -> pattern;
7878
payload: mapper -> payload -> payload;
79+
record_field:
80+
mapper -> expression record_element -> expression record_element;
81+
record_field_pat: mapper -> pattern record_element -> pattern record_element;
7982
signature: mapper -> signature -> signature;
8083
signature_item: mapper -> signature_item -> signature_item;
8184
structure: mapper -> structure -> structure;

compiler/ml/cmt_utils.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type action_type =
5454
| PipeToIgnore
5555
| PartiallyApplyFunction
5656
| InsertMissingArguments of {missing_args: Asttypes.Noloc.arg_label list}
57+
| ChangeRecordFieldOptional of {optional: bool}
5758

5859
(* TODO:
5960
- Unused var in patterns (and aliases )*)
@@ -108,6 +109,9 @@ let action_to_string = function
108109
| Asttypes.Noloc.Optional txt -> "?" ^ txt
109110
| Asttypes.Noloc.Nolabel -> "<unlabelled>")
110111
|> String.concat ", ")
112+
| ChangeRecordFieldOptional {optional} ->
113+
Printf.sprintf "ChangeRecordFieldOptional(%s)"
114+
(if optional then "true" else "false")
111115

112116
let _add_possible_action : (cmt_action -> unit) ref = ref (fun _ -> ())
113117
let add_possible_action action = !_add_possible_action action

compiler/ml/error_message_utils.ml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,12 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
589589
| ( Some (RecordField {optional = true; field_name; jsx = None}),
590590
Some ({desc = Tconstr (p, _, _)}, _) )
591591
when Path.same Predef.path_option p ->
592-
(* TODO(actions) Prepend with `?` *)
592+
Cmt_utils.add_possible_action
593+
{
594+
loc;
595+
action = ChangeRecordFieldOptional {optional = true};
596+
description = "Pass field as optional";
597+
};
593598
fprintf ppf
594599
"@,\
595600
@,\
@@ -608,7 +613,7 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
608613
| ( Some (RecordField {optional = true; field_name; jsx = Some _}),
609614
Some ({desc = Tconstr (p, _, _)}, _) )
610615
when Path.same Predef.path_option p ->
611-
(* TODO(actions) Prepend with `?` *)
616+
(* TODO(actions) JSX: Prepend with `?` *)
612617
fprintf ppf
613618
"@,\
614619
@,\
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
type record = {a: int, test?: bool}
2+
let test = Some(true)
3+
4+
let x = {a: 10, ?test}
5+
6+
/* === AVAILABLE ACTIONS:
7+
- ChangeRecordFieldOptional(true) - Pass field as optional
8+
*/
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
type record = {a: int, test?: bool}
2+
let test = Some(true)
3+
4+
let x = {a: 10, test}

tools/src/tools.ml

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1295,10 +1295,39 @@ end
12951295

12961296
module Migrate = Migrate
12971297
module Actions = struct
1298+
let change_record_field_optional (record_el : _ Parsetree.record_element)
1299+
target_loc actions =
1300+
let change_record_field_optional_action =
1301+
actions
1302+
|> List.find_map (fun (action : Cmt_utils.cmt_action) ->
1303+
match action.action with
1304+
| ChangeRecordFieldOptional {optional} when target_loc = action.loc
1305+
->
1306+
Some optional
1307+
| _ -> None)
1308+
in
1309+
match change_record_field_optional_action with
1310+
| Some opt -> {record_el with opt}
1311+
| None -> record_el
1312+
12981313
let applyActionsToFile path actions =
12991314
let mapper =
13001315
{
13011316
Ast_mapper.default_mapper with
1317+
record_field =
1318+
(fun mapper record_el ->
1319+
let record_el =
1320+
change_record_field_optional record_el record_el.x.pexp_loc
1321+
actions
1322+
in
1323+
Ast_mapper.default_mapper.record_field mapper record_el);
1324+
record_field_pat =
1325+
(fun mapper record_el ->
1326+
let record_el =
1327+
change_record_field_optional record_el record_el.x.ppat_loc
1328+
actions
1329+
in
1330+
Ast_mapper.default_mapper.record_field_pat mapper record_el);
13021331
structure_item =
13031332
(fun mapper str_item ->
13041333
let remove_rec_flag_action_locs =
@@ -1803,7 +1832,9 @@ module Actions = struct
18031832
List.mem "PartiallyApplyFunction" filter
18041833
| RewriteArgType _ -> List.mem "RewriteArgType" filter
18051834
| InsertMissingArguments _ ->
1806-
List.mem "InsertMissingArguments" filter)
1835+
List.mem "InsertMissingArguments" filter
1836+
| ChangeRecordFieldOptional _ ->
1837+
List.mem "ChangeRecordFieldOptional" filter)
18071838
in
18081839
match applyActionsToFile path possible_actions with
18091840
| Ok applied ->

0 commit comments

Comments
 (0)