Skip to content

Commit 33906c7

Browse files
committed
Clean up expression before printing.
1 parent af58896 commit 33906c7

File tree

2 files changed

+94
-31
lines changed

2 files changed

+94
-31
lines changed

src/analysis/refactor_extract_region.ml

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,44 @@ module Fresh_name = struct
2222
loop 1
2323
end
2424

25+
let clean_up_for_printing expr =
26+
let mapper =
27+
{ Ast_mapper.default_mapper with
28+
expr =
29+
(fun mapper expr ->
30+
match expr.pexp_desc with
31+
| Pexp_poly (expr, _) ->
32+
(* We also have to remove poly extra that cause unexpected "!poly!"
33+
to be printed in generated code. This happens when you try
34+
to extract the body of a method. *)
35+
expr
36+
| Pexp_construct
37+
( _,
38+
Some
39+
{ pexp_desc =
40+
Pexp_tuple
41+
(_
42+
:: ({ pexp_desc =
43+
Pexp_constant
44+
{ pconst_desc = Pconst_string _; _ };
45+
_
46+
} as const)
47+
:: _);
48+
_
49+
} ) -> const
50+
| _ -> Ast_mapper.default_mapper.expr mapper expr)
51+
}
52+
in
53+
mapper.expr mapper expr |> Parsetree_utils.expr_remove_merlin_attributes
54+
2555
module Gen = struct
2656
let unit = Longident.Lident "()" |> Location.mknoloc
2757

2858
(* Generates [let name = body]. *)
2959
let toplevel_let ~name ~body =
3060
let open Ast_helper in
3161
let pattern = Pat.mk (Ppat_var { txt = name; loc = Location.none }) in
32-
let body = Parsetree_utils.expr_remove_merlin_attributes body in
62+
let body = clean_up_for_printing body in
3363
Str.value Nonrecursive [ Vb.mk pattern body ]
3464

3565
(* Generates [let name () = body]. *)
@@ -67,7 +97,9 @@ module Gen = struct
6797

6898
let fun_apply params ~name =
6999
let open Ast_helper in
70-
let params = List.map ~f:(fun p -> (Asttypes.Nolabel, p)) params in
100+
let params =
101+
List.map ~f:(fun p -> (Asttypes.Nolabel, clean_up_for_printing p)) params
102+
in
71103
Exp.apply (ident ~name) params
72104

73105
let fun_apply_unit = fun_apply [ Ast_helper.Exp.ident unit ]
@@ -157,7 +189,9 @@ let rec occuring_vars_path node =
157189
|> List.append acc
158190
in
159191
loop [] node |> Path.Set.of_list |> Path.Set.elements |> List.rev
160-
|> List.filter ~f:(fun path -> Ident.name (Path.head path) <> "Stdlib")
192+
|> List.filter ~f:(fun path ->
193+
(* TODO: fix this *)
194+
Ident.name (Path.head path) <> "Stdlib")
161195

162196
let analyze_expr expr expr_env ~toplevel_item =
163197
let is_value_unbound path =
@@ -234,18 +268,18 @@ let extract_to_toplevel
234268
fresh_call
235269
|> Msource.text
236270
in
237-
let untyped_expr = Untypeast.untype_expression expr in
271+
let expr = Untypeast.untype_expression expr in
238272
let content =
239273
match gen_binding_kind with
240274
| Non_recursive ->
241275
let fresh_let_binding =
242-
generated_binding ~name:val_name ~body:untyped_expr
276+
generated_binding ~name:val_name ~body:expr
243277
|> Format.asprintf "%a" Pprintast.structure_item
244278
in
245279
fresh_let_binding ^ "\n" ^ substitued_toplevel_binding
246280
| Rec_and ->
247281
let fresh_let_binding =
248-
generated_binding ~name:val_name ~body:untyped_expr
282+
generated_binding ~name:val_name ~body:expr
249283
|> Format.asprintf "%a" Pprintast.structure_item
250284
in
251285
let fresh_and_binding =
@@ -326,17 +360,23 @@ let extract_expr_to_toplevel ?extract_name expr ~expr_env ~toplevel_item =
326360
| None -> Default { basename = "fun_name" }
327361
| Some name -> Fixed name
328362
in
329-
let remove_path_prefix mapper expr =
330-
match expr.Typedtree.exp_desc with
331-
| Texp_ident (Pdot (path, val_name), longident, vd)
332-
when is_bound_var path && is_module_bound path ->
333-
let ident = { longident with txt = Longident.Lident val_name } in
334-
{ expr with exp_desc = Texp_ident (path, ident, vd) }
335-
| _ -> Tast_mapper.default.expr mapper expr
363+
let remove_path_prefix expr =
364+
let mapper =
365+
{ Tast_mapper.default with
366+
expr =
367+
(fun mapper expr ->
368+
match expr.Typedtree.exp_desc with
369+
| Texp_ident (Pdot (path, val_name), longident, vd)
370+
when is_bound_var path && is_module_bound path ->
371+
let ident = { longident with txt = Longident.Lident val_name } in
372+
{ expr with exp_desc = Texp_ident (path, ident, vd) }
373+
| _ -> Tast_mapper.default.expr mapper expr)
374+
}
375+
in
376+
mapper.expr mapper expr
336377
in
337-
let mapper = { Tast_mapper.default with expr = remove_path_prefix } in
338378
extract_to_toplevel
339-
{ expr = mapper.expr mapper expr;
379+
{ expr = remove_path_prefix expr;
340380
expr_env;
341381
toplevel_item;
342382
name;
@@ -346,17 +386,6 @@ let extract_expr_to_toplevel ?extract_name expr ~expr_env ~toplevel_item =
346386
call_need_parenthesis = true
347387
}
348388

349-
let remove_poly expr =
350-
let open Typedtree in
351-
{ expr with
352-
exp_extra =
353-
List.filter
354-
~f:(function
355-
| Texp_poly _, _, _ -> false
356-
| _ -> true)
357-
expr.exp_extra
358-
}
359-
360389
let most_inclusive_expr ~start ~stop nodes =
361390
let is_inside_region =
362391
Location_aux.included
@@ -382,11 +411,6 @@ let most_inclusive_expr ~start ~stop nodes =
382411
in
383412
nodes |> List.rev
384413
|> Stdlib.List.find_map (fun (env, node) -> select_among_child env node)
385-
|> Option.map ~f:(fun (expr, env) ->
386-
(* We also have to remove poly extra that cause unexpected "!poly!"
387-
to be printed in generated code. This happens when you try to extract
388-
the body of a method. *)
389-
(remove_poly expr, env))
390414

391415
let find_associated_toplevel_item expr enclosing =
392416
Stdlib.List.find_map

tests/test-dirs/refactor-extract-region/func-extraction.t/run.t

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,7 @@ TODO: This extraction shouldn't be allowed.
796796
},
797797
"notifications": []
798798
}
799+
799800
$ $MERLIN single refactoring-extract-region -start 154:18 -end 154:44 < func.ml
800801
{
801802
"class": "return",
@@ -828,3 +829,41 @@ TODO: This extraction shouldn't be allowed.
828829
},
829830
"notifications": []
830831
}
832+
833+
$ $MERLIN single refactoring-extract-region -start 128:2 -end 133:7 < func.ml
834+
{
835+
"class": "return",
836+
"value": {
837+
"start": {
838+
"line": 125,
839+
"col": 0
840+
},
841+
"end": {
842+
"line": 133,
843+
"col": 7
844+
},
845+
"content": "let fun_name2 (ppf) (doc) (bold_tag) =
846+
fprintf ppf \"%a\"
847+
(pp_print_list ?pp_sep:None
848+
(fun ppf markup ->
849+
match markup with
850+
| Text txt -> pp_print_string ppf txt
851+
| Bold txt -> pp_print_string ppf (bold_tag ^ (txt ^ bold_tag))))
852+
doc
853+
let pp_document ppf doc =
854+
let open Format in
855+
let bold_tag = \"**\" in
856+
(fun_name2 ppf doc bold_tag)",
857+
"selection-range": {
858+
"start": {
859+
"line": 125,
860+
"col": 4
861+
},
862+
"end": {
863+
"line": 125,
864+
"col": 13
865+
}
866+
}
867+
},
868+
"notifications": []
869+
}

0 commit comments

Comments
 (0)