| 
1 | 1 | type extract_concrete_typedecl =  | 
2 | 2 |   Env.t -> Types.type_expr -> Path.t * Path.t * Types.type_declaration  | 
3 | 3 | 
 
  | 
4 |  | -type comment  | 
5 |  | -let parse_source : (string -> Parsetree.structure * comment list) ref =  | 
6 |  | -  ref (fun _ -> ([], []))  | 
7 |  | -let reprint_source : (Parsetree.structure -> comment list -> string) ref =  | 
8 |  | -  ref (fun _ _ -> "")  | 
 | 4 | +module Parser : sig  | 
 | 5 | +  type comment  | 
 | 6 | + | 
 | 7 | +  val parse_source : (string -> Parsetree.structure * comment list) ref  | 
 | 8 | + | 
 | 9 | +  val reprint_source : (Parsetree.structure -> comment list -> string) ref  | 
 | 10 | + | 
 | 11 | +  val parse_expr_at_loc :  | 
 | 12 | +    Warnings.loc -> (Parsetree.expression * comment list) option  | 
 | 13 | + | 
 | 14 | +  val reprint_expr_at_loc :  | 
 | 15 | +    ?mapper:(Parsetree.expression -> Parsetree.expression option) ->  | 
 | 16 | +    Warnings.loc ->  | 
 | 17 | +    string option  | 
 | 18 | +end = struct  | 
 | 19 | +  type comment  | 
 | 20 | + | 
 | 21 | +  let parse_source : (string -> Parsetree.structure * comment list) ref =  | 
 | 22 | +    ref (fun _ -> ([], []))  | 
 | 23 | + | 
 | 24 | +  let reprint_source : (Parsetree.structure -> comment list -> string) ref =  | 
 | 25 | +    ref (fun _ _ -> "")  | 
 | 26 | + | 
 | 27 | +  let extract_location_string ~src (loc : Location.t) =  | 
 | 28 | +    let start_pos = loc.loc_start in  | 
 | 29 | +    let end_pos = loc.loc_end in  | 
 | 30 | +    let start_offset = start_pos.pos_cnum in  | 
 | 31 | +    let end_offset = end_pos.pos_cnum in  | 
 | 32 | +    String.sub src start_offset (end_offset - start_offset)  | 
 | 33 | + | 
 | 34 | +  let parse_expr_at_loc loc =  | 
 | 35 | +    (* TODO: Maybe cache later on *)  | 
 | 36 | +    let src = Ext_io.load_file loc.Location.loc_start.pos_fname in  | 
 | 37 | +    let sub_src = extract_location_string ~src loc in  | 
 | 38 | +    let parsed, comments = !parse_source sub_src in  | 
 | 39 | +    match parsed with  | 
 | 40 | +    | [{Parsetree.pstr_desc = Pstr_eval (exp, _)}] -> Some (exp, comments)  | 
 | 41 | +    | _ -> None  | 
 | 42 | + | 
 | 43 | +  let wrap_in_structure exp =  | 
 | 44 | +    [{Parsetree.pstr_desc = Pstr_eval (exp, []); pstr_loc = Location.none}]  | 
 | 45 | + | 
 | 46 | +  let reprint_expr_at_loc ?(mapper = fun _ -> None) loc =  | 
 | 47 | +    match parse_expr_at_loc loc with  | 
 | 48 | +    | Some (exp, comments) -> (  | 
 | 49 | +      match mapper exp with  | 
 | 50 | +      | Some exp -> Some (!reprint_source (wrap_in_structure exp) comments)  | 
 | 51 | +      | None -> None)  | 
 | 52 | +    | None -> None  | 
 | 53 | +end  | 
9 | 54 | 
  | 
10 | 55 | type type_clash_statement = FunctionCall  | 
11 | 56 | type type_clash_context =  | 
@@ -68,13 +113,6 @@ let is_record_type ~extract_concrete_typedecl ~env ty =  | 
68 | 113 |     | _ -> false  | 
69 | 114 |   with _ -> false  | 
70 | 115 | 
  | 
71 |  | -let extract_location_string ~src (loc : Location.t) =  | 
72 |  | -  let start_pos = loc.loc_start in  | 
73 |  | -  let end_pos = loc.loc_end in  | 
74 |  | -  let start_offset = start_pos.pos_cnum in  | 
75 |  | -  let end_offset = end_pos.pos_cnum in  | 
76 |  | -  String.sub src start_offset (end_offset - start_offset)  | 
77 |  | - | 
78 | 116 | let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf  | 
79 | 117 |     (bottom_aliases : (Types.type_expr * Types.type_expr) option)  | 
80 | 118 |     type_clash_context =  | 
@@ -200,28 +238,12 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf  | 
200 | 238 |     fprintf ppf "\n\n  - Did you mean to await this promise before using it?\n"  | 
201 | 239 |   | _, Some ({Types.desc = Tconstr (p1, _, _)}, {Types.desc = Ttuple _})  | 
202 | 240 |     when Path.same p1 Predef.path_array ->  | 
203 |  | -    let src = Ext_io.load_file loc.Location.loc_start.pos_fname in  | 
204 |  | -    let sub_src = extract_location_string ~src loc in  | 
205 |  | -    let parsed, comments = !parse_source sub_src in  | 
206 | 241 |     let suggested_rewrite =  | 
207 |  | -      match parsed with  | 
208 |  | -      | [  | 
209 |  | -       ({  | 
210 |  | -          Parsetree.pstr_desc =  | 
211 |  | -            Pstr_eval (({pexp_desc = Pexp_array items} as exp), l);  | 
212 |  | -        } as str_item);  | 
213 |  | -      ] ->  | 
214 |  | -        Some  | 
215 |  | -          (!reprint_source  | 
216 |  | -             [  | 
217 |  | -               {  | 
218 |  | -                 str_item with  | 
219 |  | -                 pstr_desc =  | 
220 |  | -                   Pstr_eval ({exp with pexp_desc = Pexp_tuple items}, l);  | 
221 |  | -               };  | 
222 |  | -             ]  | 
223 |  | -             comments)  | 
224 |  | -      | _ -> None  | 
 | 242 | +      Parser.reprint_expr_at_loc loc ~mapper:(fun exp ->  | 
 | 243 | +          match exp.Parsetree.pexp_desc with  | 
 | 244 | +          | Pexp_array items ->  | 
 | 245 | +            Some {exp with Parsetree.pexp_desc = Pexp_tuple items}  | 
 | 246 | +          | _ -> None)  | 
225 | 247 |     in  | 
226 | 248 |     fprintf ppf  | 
227 | 249 |       "\n\n  - Fix this by passing a tuple instead of an array%s@{<info>%s@}\n"  | 
 | 
0 commit comments