Skip to content

Commit 565d2a9

Browse files
committed
move away from cmt to an explicit sidecar extras file
1 parent 284103a commit 565d2a9

File tree

22 files changed

+213
-102
lines changed

22 files changed

+213
-102
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ _build
1111
*.cmx
1212
*.cmt
1313
*.cmti
14+
*.resextra
1415
*.cma
1516
*.a
1617
*.cmxa

analysis/src/Cmt.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ let fullFromUri ~uri =
3838
let cmt = getCmtPath ~uri paths in
3939
fullForCmt ~moduleName ~package ~uri cmt
4040
| None ->
41-
prerr_endline ("can't find module " ^ moduleName);
41+
if not (Uri.isInterface uri) then
42+
prerr_endline ("can't find module " ^ moduleName);
4243
None))
4344

4445
let fullsFromModule ~package ~moduleName =

analysis/src/Resextra.ml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
let extrasPathFromCmtPath cmtPath =
2+
if Filename.check_suffix cmtPath ".cmti" then
3+
Filename.chop_extension cmtPath ^ ".resiextra"
4+
else if Filename.check_suffix cmtPath ".cmt" then
5+
Filename.chop_extension cmtPath ^ ".resextra"
6+
else cmtPath ^ ".resextra"
7+
8+
let loadActionsFromPackage ~path ~package =
9+
let uri = Uri.fromPath path in
10+
let moduleName =
11+
BuildSystem.namespacedName package.SharedTypes.namespace
12+
(FindFiles.getName path)
13+
in
14+
match Hashtbl.find_opt package.SharedTypes.pathsForModule moduleName with
15+
| None -> None
16+
| Some paths ->
17+
let cmtPath = SharedTypes.getCmtPath ~uri paths in
18+
let extrasPath = extrasPathFromCmtPath cmtPath in
19+
20+
let tryLoad path =
21+
if Sys.file_exists path then
22+
try
23+
let ic = open_in_bin path in
24+
let v = (input_value ic : Actions.action list) in
25+
close_in ic;
26+
Some v
27+
with _ -> None
28+
else None
29+
in
30+
tryLoad extrasPath

analysis/src/Xform.ml

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,28 @@ let parseInterface ~filename =
897897
let extractCodeActions ~path ~startPos ~endPos ~currentFile ~debug =
898898
let pos = startPos in
899899
let codeActions = ref [] in
900+
let add_actions_from_extras ~path ~pos ~package ~codeActions =
901+
let map_extra_action (a : Actions.action) =
902+
match a.action with
903+
| Actions.RemoveOpen ->
904+
let range = Loc.rangeOfLoc a.loc in
905+
let newText = "" in
906+
Some
907+
(CodeActions.make ~title:a.description ~kind:RefactorRewrite ~uri:path
908+
~newText ~range)
909+
| _ -> None
910+
in
911+
match Resextra.loadActionsFromPackage ~path ~package with
912+
| None -> ()
913+
| Some actions ->
914+
let relevant =
915+
actions
916+
|> List.filter (fun (a : Actions.action) -> Loc.hasPos ~pos a.loc)
917+
in
918+
relevant
919+
|> List.filter_map map_extra_action
920+
|> List.iter (fun ca -> codeActions := ca :: !codeActions)
921+
in
900922
match Files.classifySourceFile currentFile with
901923
| Res ->
902924
let structure, printExpr, printStructureItem, printStandaloneStructure =
@@ -920,7 +942,8 @@ let extractCodeActions ~path ~startPos ~endPos ~currentFile ~debug =
920942
~pos:
921943
(if startPos = endPos then Single startPos
922944
else Range (startPos, endPos))
923-
~full ~structure ~codeActions ~debug ~currentFile
945+
~full ~structure ~codeActions ~debug ~currentFile;
946+
add_actions_from_extras ~path ~pos ~package:full.package ~codeActions
924947
| None -> ()
925948
in
926949

@@ -929,5 +952,8 @@ let extractCodeActions ~path ~startPos ~endPos ~currentFile ~debug =
929952
let signature, printSignatureItem = parseInterface ~filename:currentFile in
930953
AddDocTemplate.Interface.xform ~pos ~codeActions ~path ~signature
931954
~printSignatureItem;
955+
(match Packages.getPackage ~uri:(Uri.fromPath path) with
956+
| Some package -> add_actions_from_extras ~path ~pos ~package ~codeActions
957+
| None -> ());
932958
!codeActions
933959
| Other -> []

compiler/bsc/rescript_compiler_main.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,9 @@ let _ : unit =
437437
Bs_conditional_initial.setup_env ();
438438
Clflags.color := Some Always;
439439

440+
(* Save extras (e.g., actions) once before exit, after all reporting. *)
441+
at_exit (fun () -> Res_extra.save ());
442+
440443
let flags = "flags" in
441444
Ast_config.add_structure flags file_level_flags_handler;
442445
Ast_config.add_signature flags file_level_flags_handler;
@@ -446,6 +449,4 @@ let _ : unit =
446449
exit 2
447450
| x ->
448451
Location.report_exception ppf x;
449-
(* Re-save cmt so we can get the possible actions *)
450-
Cmt_format.resave_cmt_with_possible_actions ();
451452
exit 2

compiler/core/js_implementation.ml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ let after_parsing_sig ppf outputprefix ast =
4949
if !Js_config.syntax_only then Warnings.check_fatal ()
5050
else
5151
let modulename = module_of_filename outputprefix in
52+
Res_extra.set_is_interface true;
53+
Res_extra.set_current_outputprefix (Some outputprefix);
5254
Lam_compile_env.reset ();
5355
let initial_env = Res_compmisc.initial_env ~modulename () in
5456
Env.set_unit_name modulename;
@@ -65,7 +67,9 @@ let after_parsing_sig ppf outputprefix ast =
6567
in
6668
Typemod.save_signature modulename tsg outputprefix !Location.input_name
6769
initial_env sg;
68-
process_with_gentype (outputprefix ^ ".cmti"))
70+
process_with_gentype (outputprefix ^ ".cmti");
71+
(* Persist any collected code actions to .resextra sidecar *)
72+
Res_extra.save ())
6973

7074
let interface ~parser ppf ?outputprefix fname =
7175
let outputprefix =
@@ -130,6 +134,8 @@ let after_parsing_impl ppf outputprefix (ast : Parsetree.structure) =
130134
if !Js_config.syntax_only then Warnings.check_fatal ()
131135
else
132136
let modulename = Ext_filename.module_name outputprefix in
137+
Res_extra.set_is_interface false;
138+
Res_extra.set_current_outputprefix (Some outputprefix);
133139
Lam_compile_env.reset ();
134140
let env = Res_compmisc.initial_env ~modulename () in
135141
Env.set_unit_name modulename;
@@ -152,7 +158,9 @@ let after_parsing_impl ppf outputprefix (ast : Parsetree.structure) =
152158
in
153159
if not !Js_config.cmj_only then
154160
Lam_compile_main.lambda_as_module js_program outputprefix);
155-
process_with_gentype (outputprefix ^ ".cmt"))
161+
process_with_gentype (outputprefix ^ ".cmt");
162+
(* Persist any collected code actions to .resextra sidecar *)
163+
Res_extra.save ())
156164

157165
let implementation ~parser ppf ?outputprefix fname =
158166
let outputprefix =

compiler/ml/cmt_utils.ml renamed to compiler/ml/actions.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ type action_type =
2929
(* TODO:
3030
- Unused var in patterns (and aliases )*)
3131

32-
type cmt_action = {loc: Location.t; action: action_type; description: string}
32+
type action = {loc: Location.t; action: action_type; description: string}
3333

3434
let action_to_string = function
3535
| ApplyFunction {function_name} ->
@@ -86,7 +86,7 @@ let action_to_string = function
8686
Printf.sprintf "UnwrapOptionMapRecordField(%s)"
8787
(Longident.flatten field_name |> String.concat ".")
8888

89-
let _add_possible_action : (cmt_action -> unit) ref = ref (fun _ -> ())
89+
let _add_possible_action : (action -> unit) ref = ref (fun _ -> ())
9090
let add_possible_action action = !_add_possible_action action
9191

9292
let emit_possible_actions_from_warning loc w =

compiler/ml/cmt_format.ml

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ type cmt_infos = {
6363
cmt_imports : (string * Digest.t option) list;
6464
cmt_interface_digest : Digest.t option;
6565
cmt_use_summaries : bool;
66-
cmt_possible_actions : Cmt_utils.cmt_action list;
6766
}
6867

6968
type error =
@@ -155,22 +154,15 @@ let read_cmi filename =
155154

156155
let saved_types = ref []
157156
let value_deps = ref []
158-
let possible_actions = ref []
159157

160158
let clear () =
161159
saved_types := [];
162-
value_deps := [];
163-
possible_actions := []
160+
value_deps := []
164161

165162
let add_saved_type b = saved_types := b :: !saved_types
166163
let get_saved_types () = !saved_types
167164
let set_saved_types l = saved_types := l
168165

169-
let add_possible_action action =
170-
possible_actions := action :: !possible_actions
171-
172-
let _ = Cmt_utils._add_possible_action := add_possible_action
173-
174166
let record_value_dependency vd1 vd2 =
175167
if vd1.Types.val_loc <> vd2.Types.val_loc then
176168
value_deps := (vd1, vd2) :: !value_deps
@@ -180,30 +172,8 @@ let save_cmt _filename _modname _binary_annots _sourcefile _initial_env _cmi = (
180172
#else
181173
open Cmi_format
182174

183-
let current_cmt_filename = ref None
184-
185-
(* TODO: Terrible hack. Figure out way to do this without saving the cmt file twice.
186-
Probably change how/where we save the cmt, and delay it to after writing errors, if possible.
187-
*)
188-
let resave_cmt_with_possible_actions () =
189-
if List.length !possible_actions > 0 then begin
190-
match !current_cmt_filename with
191-
| None -> ()
192-
| Some filename ->
193-
let current_cmt = read_cmt filename in
194-
Misc.output_to_bin_file_directly filename
195-
(fun _temp_file_name oc ->
196-
let cmt = {
197-
current_cmt with
198-
cmt_possible_actions = current_cmt.cmt_possible_actions @ !possible_actions;
199-
} in
200-
output_cmt oc cmt)
201-
end;
202-
clear ()
203-
204175
let save_cmt filename modname binary_annots sourcefile initial_env cmi =
205176
if !Clflags.binary_annotations then begin
206-
current_cmt_filename := Some filename;
207177
Misc.output_to_bin_file_directly filename
208178
(fun temp_file_name oc ->
209179
let this_crc =
@@ -227,7 +197,6 @@ let save_cmt filename modname binary_annots sourcefile initial_env cmi =
227197
cmt_imports = List.sort compare (Env.imports ());
228198
cmt_interface_digest = this_crc;
229199
cmt_use_summaries = need_to_clear_env;
230-
cmt_possible_actions = !possible_actions;
231200
} in
232201
output_cmt oc cmt)
233202
end;

compiler/ml/cmt_format.mli

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ type cmt_infos = {
6363
cmt_imports: (string * Digest.t option) list;
6464
cmt_interface_digest: Digest.t option;
6565
cmt_use_summaries: bool;
66-
cmt_possible_actions: Cmt_utils.cmt_action list;
6766
}
6867

6968
type error = Not_a_typedtree of string
@@ -112,8 +111,6 @@ val set_saved_types : binary_part list -> unit
112111
val record_value_dependency :
113112
Types.value_description -> Types.value_description -> unit
114113

115-
val resave_cmt_with_possible_actions : unit -> unit
116-
117114
(*
118115
119116
val is_magic_number : string -> bool

compiler/ml/error_message_utils.ml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
389389
\ To fix this, change the highlighted code so it evaluates to a \
390390
@{<info>bool@}."
391391
| Some Await, _ ->
392-
Cmt_utils.add_possible_action
392+
Actions.add_possible_action
393393
{loc; action = RemoveAwait; description = "Remove await"};
394394
fprintf ppf
395395
"\n\n\
@@ -417,7 +417,7 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
417417
| Some ComparisonOperator, _ ->
418418
fprintf ppf "\n\n You can only compare things of the same type."
419419
| Some ArrayValue, _ ->
420-
Cmt_utils.add_possible_action
420+
Actions.add_possible_action
421421
{loc; action = RewriteArrayToTuple; description = "Rewrite to tuple"};
422422
fprintf ppf
423423
"\n\n\
@@ -478,7 +478,7 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
478478
Some record
479479
| _ -> None)
480480
in
481-
Cmt_utils.add_possible_action
481+
Actions.add_possible_action
482482
{
483483
loc;
484484
action = RewriteObjectToRecord;
@@ -498,7 +498,7 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
498498
| _, Some ({Types.desc = Tconstr (p1, _, _)}, _)
499499
when Path.same p1 Predef.path_promise ->
500500
(* TODO: This should be aware of if we're in an async context or not? *)
501-
Cmt_utils.add_possible_action
501+
Actions.add_possible_action
502502
{loc; action = AddAwait; description = "Await promise"};
503503
fprintf ppf "\n\n - Did you mean to await this promise before using it?\n"
504504
| _, Some ({Types.desc = Tconstr (p1, _, _)}, {Types.desc = Ttuple _})
@@ -507,7 +507,7 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
507507
Parser.reprint_expr_at_loc loc ~mapper:(fun exp ->
508508
match exp.Parsetree.pexp_desc with
509509
| Pexp_array items ->
510-
Cmt_utils.add_possible_action
510+
Actions.add_possible_action
511511
{
512512
loc;
513513
action = RewriteArrayToTuple;
@@ -538,7 +538,7 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
538538
in
539539
540540
let print_jsx_msg ?(extra = "") name target_fn =
541-
Cmt_utils.add_possible_action
541+
Actions.add_possible_action
542542
{
543543
loc;
544544
action = ApplyFunction {function_name = Longident.parse target_fn};
@@ -589,7 +589,7 @@ 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-
Cmt_utils.add_possible_action
592+
Actions.add_possible_action
593593
{
594594
loc;
595595
action = ChangeRecordFieldOptional {optional = true};
@@ -632,7 +632,7 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
632632
| ( Some (FunctionArgument {optional = true}),
633633
Some ({desc = Tconstr (p, _, _)}, _) )
634634
when Path.same Predef.path_option p ->
635-
Cmt_utils.add_possible_action
635+
Actions.add_possible_action
636636
{
637637
loc;
638638
action = RewriteArgType {to_type = `Optional};
@@ -696,7 +696,7 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
696696
in
697697
match (reprinted, List.mem string_value variant_constructors) with
698698
| Some reprinted, true ->
699-
Cmt_utils.add_possible_action
699+
Actions.add_possible_action
700700
{
701701
loc;
702702
action =
@@ -763,7 +763,7 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
763763
in
764764
match reprinted with
765765
| Some reprinted ->
766-
Cmt_utils.add_possible_action
766+
Actions.add_possible_action
767767
{
768768
loc;
769769
action =
@@ -829,7 +829,7 @@ let print_extra_type_clash_help ~extract_concrete_typedecl ~env loc ppf
829829
in
830830
831831
if can_show_coercion_message && not is_constant then (
832-
Cmt_utils.add_possible_action
832+
Actions.add_possible_action
833833
{
834834
loc;
835835
action =

0 commit comments

Comments
 (0)