Skip to content

Commit 16694f6

Browse files
committed
pass record field expr as optional
1 parent 4dfa741 commit 16694f6

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;
@@ -311,11 +313,7 @@ module E = struct
311313
iter_opt (sub.expr sub) arg
312314
| Pexp_variant (_lab, eo) -> iter_opt (sub.expr sub) eo
313315
| Pexp_record (l, eo) ->
314-
List.iter
315-
(fun {lid; x = exp} ->
316-
iter_loc sub lid;
317-
sub.expr sub exp)
318-
l;
316+
List.iter (sub.record_field sub) l;
319317
iter_opt (sub.expr sub) eo
320318
| Pexp_field (e, lid) ->
321319
sub.expr sub e;
@@ -401,12 +399,7 @@ module P = struct
401399
iter_loc sub l;
402400
iter_opt (sub.pat sub) p
403401
| Ppat_variant (_l, p) -> iter_opt (sub.pat sub) p
404-
| Ppat_record (lpl, _cf) ->
405-
List.iter
406-
(fun {lid; x = pat} ->
407-
iter_loc sub lid;
408-
sub.pat sub pat)
409-
lpl
402+
| Ppat_record (lpl, _cf) -> List.iter (sub.record_field_pat sub) lpl
410403
| Ppat_array pl -> List.iter (sub.pat sub) pl
411404
| Ppat_or (p1, p2) ->
412405
sub.pat sub p1;
@@ -530,4 +523,12 @@ let default_iterator =
530523
| PPat (x, g) ->
531524
this.pat this x;
532525
iter_opt (this.expr this) g);
526+
record_field =
527+
(fun this {lid; x; opt = _} ->
528+
iter_loc this lid;
529+
this.expr this x);
530+
record_field_pat =
531+
(fun this {lid; x; opt = _} ->
532+
iter_loc this lid;
533+
this.pat this x);
533534
}

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;
@@ -307,10 +310,7 @@ module E = struct
307310
variant ~loc ~attrs lab (map_opt (sub.expr sub) eo)
308311
| Pexp_record (l, eo) ->
309312
record ~loc ~attrs
310-
(List.map
311-
(fun {lid; x = exp; opt} ->
312-
{lid = map_loc sub lid; x = sub.expr sub exp; opt})
313-
l)
313+
(List.map (sub.record_field sub) l)
314314
(map_opt (sub.expr sub) eo)
315315
| Pexp_field (e, lid) ->
316316
field ~loc ~attrs (sub.expr sub e) (map_loc sub lid)
@@ -393,12 +393,7 @@ module P = struct
393393
construct ~loc ~attrs (map_loc sub l) (map_opt (sub.pat sub) p)
394394
| Ppat_variant (l, p) -> variant ~loc ~attrs l (map_opt (sub.pat sub) p)
395395
| Ppat_record (lpl, cf) ->
396-
record ~loc ~attrs
397-
(List.map
398-
(fun {lid; x = pat; opt} ->
399-
{lid = map_loc sub lid; x = sub.pat sub pat; opt})
400-
lpl)
401-
cf
396+
record ~loc ~attrs (List.map (sub.record_field_pat sub) lpl) cf
402397
| Ppat_array pl -> array ~loc ~attrs (List.map (sub.pat sub) pl)
403398
| Ppat_or (p1, p2) -> or_ ~loc ~attrs (sub.pat sub p1) (sub.pat sub p2)
404399
| Ppat_constraint (p, t) ->
@@ -511,6 +506,12 @@ let default_mapper =
511506
| PSig x -> PSig (this.signature this x)
512507
| PTyp x -> PTyp (this.typ this x)
513508
| PPat (x, g) -> PPat (this.pat this x, map_opt (this.expr this) g));
509+
record_field =
510+
(fun this {lid; x; opt} ->
511+
{lid = map_loc this lid; x = this.expr this x; opt});
512+
record_field_pat =
513+
(fun this {lid; x; opt} ->
514+
{lid = map_loc this lid; x = this.pat this x; opt});
514515
}
515516

516517
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
@@ -23,6 +23,7 @@ type action_type =
2323
| PipeToIgnore
2424
| PartiallyApplyFunction
2525
| InsertMissingArguments of {missing_args: Asttypes.Noloc.arg_label list}
26+
| ChangeRecordFieldOptional of {optional: bool}
2627

2728
(* TODO:
2829
- Unused var in patterns (and aliases )*)
@@ -77,6 +78,9 @@ let action_to_string = function
7778
| Asttypes.Noloc.Optional txt -> "?" ^ txt
7879
| Asttypes.Noloc.Nolabel -> "<unlabelled>")
7980
|> String.concat ", ")
81+
| ChangeRecordFieldOptional {optional} ->
82+
Printf.sprintf "ChangeRecordFieldOptional(%s)"
83+
(if optional then "true" else "false")
8084

8185
let _add_possible_action : (cmt_action -> unit) ref = ref (fun _ -> ())
8286
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
@@ -515,7 +515,12 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
515515
| ( Some (RecordField {optional = true; field_name; jsx = None}),
516516
Some ({desc = Tconstr (p, _, _)}, _) )
517517
when Path.same Predef.path_option p ->
518-
(* TODO(actions) Prepend with `?` *)
518+
Cmt_utils.add_possible_action
519+
{
520+
loc;
521+
action = ChangeRecordFieldOptional {optional = true};
522+
description = "Pass field as optional";
523+
};
519524
fprintf ppf
520525
"@,\
521526
@,\
@@ -534,7 +539,7 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
534539
| ( Some (RecordField {optional = true; field_name; jsx = Some _}),
535540
Some ({desc = Tconstr (p, _, _)}, _) )
536541
when Path.same Predef.path_option p ->
537-
(* TODO(actions) Prepend with `?` *)
542+
(* TODO(actions) JSX: Prepend with `?` *)
538543
fprintf ppf
539544
"@,\
540545
@,\
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
@@ -1294,10 +1294,39 @@ module ExtractCodeblocks = struct
12941294
end
12951295

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

0 commit comments

Comments
 (0)