@@ -41,7 +41,7 @@ type error =
4141 | Cannot_quantify of string * type_expr
4242 | Multiple_constraints_on_type of Longident .t
4343 | Method_mismatch of string * type_expr * type_expr
44- | Unbound_value of Longident .t
44+ | Unbound_value of Longident .t * Location .t
4545 | Unbound_constructor of Longident .t
4646 | Unbound_label of Longident .t * type_expr option
4747 | Unbound_module of Longident .t
@@ -134,7 +134,9 @@ let find_all_labels =
134134let find_value env loc lid =
135135 Env. check_value_name (Longident. last lid) loc;
136136 let ((path, decl) as r ) =
137- find_component Env. lookup_value (fun lid -> Unbound_value lid) env loc lid
137+ find_component Env. lookup_value
138+ (fun lid -> Unbound_value (lid, loc))
139+ env loc lid
138140 in
139141 Builtin_attributes. check_deprecated loc decl.val_attributes (Path. name path);
140142 r
@@ -720,29 +722,29 @@ let transl_type_scheme env styp =
720722open Format
721723open Printtyp
722724
723- let did_you_mean ppf choices : bool =
725+ let did_you_mean ppf choices : bool * string list =
724726 (* flush now to get the error report early, in the (unheard of) case
725727 where the linear search would take a bit of time; in the worst
726728 case, the user has seen the error, she can interrupt the process
727729 before the spell-checking terminates. *)
728730 Format. fprintf ppf " @?" ;
729731 match choices () with
730- | [] -> false
731- | last :: rev_rest ->
732+ | [] -> ( false , [] )
733+ | last :: rev_rest as choices ->
732734 (* TODO(actions) Rewrite ident *)
733735 Format. fprintf ppf " @[<v 2>@,@,@{<info>Hint: Did you mean %s%s%s?@}@]"
734736 (String. concat " , " (List. rev rev_rest))
735737 (if rev_rest = [] then " " else " or " )
736738 last;
737- true
739+ ( true , choices)
738740
739741let super_spellcheck ppf fold env lid =
740742 let choices path name : string list =
741743 let env : string list = fold (fun x _ _ xs -> x :: xs) path env [] in
742744 Misc. spellcheck env name
743745 in
744746 match lid with
745- | Longident. Lapply _ -> false
747+ | Longident. Lapply _ -> ( false , [] )
746748 | Longident. Lident s -> did_you_mean ppf (fun _ -> choices None s)
747749 | Longident. Ldot (r , s ) -> did_you_mean ppf (fun _ -> choices (Some r) s)
748750
@@ -774,7 +776,7 @@ let report_error env ppf = function
774776 (* modified *)
775777 Format. fprintf ppf " @[<v>This type constructor, `%a`, can't be found.@ "
776778 Printtyp. longident lid;
777- let has_candidate = super_spellcheck ppf Env. fold_types env lid in
779+ let has_candidate, _ = super_spellcheck ppf Env. fold_types env lid in
778780 if not has_candidate then
779781 (* TODO(actions) Add rec flag *)
780782 Format. fprintf ppf
@@ -846,7 +848,7 @@ let report_error env ppf = function
846848 Printtyp. reset_and_mark_loops_list [ty; ty'];
847849 fprintf ppf " @[<hov>Method '%s' has type %a,@ which should be %a@]" l
848850 Printtyp. type_expr ty Printtyp. type_expr ty')
849- | Unbound_value lid -> (
851+ | Unbound_value ( lid , loc ) -> (
850852 (* modified *)
851853 (match lid with
852854 | Ldot (outer , inner ) ->
@@ -855,12 +857,22 @@ let report_error env ppf = function
855857 | other_ident ->
856858 Format. fprintf ppf " The value %a can't be found" Printtyp. longident
857859 other_ident);
858- let did_spellcheck = super_spellcheck ppf Env. fold_values env lid in
860+ let did_spellcheck, choices =
861+ super_spellcheck ppf Env. fold_values env lid
862+ in
863+ if did_spellcheck then
864+ choices
865+ |> List. iter (fun choice ->
866+ Cmt_utils. add_possible_action
867+ {
868+ loc;
869+ action = Cmt_utils. RewriteIdent {new_ident = Lident choice};
870+ description = " Change to `" ^ choice ^ " `" ;
871+ });
859872 (* For cases such as when the user refers to something that's a value with
860873 a lowercase identifier in JS but a module in ReScript.
861874
862875 'Console' is a typical example, where JS is `console.log` and ReScript is `Console.log`. *)
863- (* TODO(codemods) Add codemod for refering to the module instead. *)
864876 let as_module =
865877 match lid with
866878 | Lident name -> (
@@ -875,7 +887,18 @@ let report_error env ppf = function
875887 match as_module with
876888 | None -> ()
877889 | Some module_path ->
878- (* TODO(actions) Rewrite ident *)
890+ let new_ident =
891+ module_path |> Printtyp. string_of_path |> Longident. parse
892+ in
893+ Cmt_utils. add_possible_action
894+ {
895+ loc;
896+ action = Cmt_utils. RewriteIdent {new_ident};
897+ description =
898+ " Change to `"
899+ ^ (new_ident |> Longident. flatten |> String. concat " ." )
900+ ^ " `" ;
901+ };
879902 Format. fprintf ppf " @,@[<v 2>@,@[%s to use the module @{<info>%a@}?@]@]"
880903 (if did_spellcheck then " Or did you mean" else " Maybe you meant" )
881904 Printtyp. path module_path)
0 commit comments