Skip to content

Commit b9837af

Browse files
committed
add editor mode to compiler that lets you continue past certain type errors to produce more type information
1 parent 38f9c6f commit b9837af

File tree

6 files changed

+47
-1
lines changed

6 files changed

+47
-1
lines changed

compiler/bsc/rescript_compiler_main.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,9 @@ let buckle_script_flags : (string * Bsc_args.spec * string) array =
369369
( "-ignore-parse-errors",
370370
set Clflags.ignore_parse_errors,
371371
"*internal* continue after parse errors" );
372+
( "-editor-mode",
373+
set Clflags.editor_mode,
374+
"*internal* editor mode. Adapts compilation for editors." );
372375
( "-where",
373376
unit_call print_standard_library,
374377
"*internal* Print location of standard library and exit" );

compiler/ml/clflags.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ and only_parse = ref false (* -only-parse *)
4242

4343
and ignore_parse_errors = ref false (* -ignore-parse-errors *)
4444

45+
and editor_mode = ref true
46+
(* -editor-mode *)
47+
(* true for easy testing *)
48+
4549
let dont_write_files = ref false (* set to true under ocamldoc *)
4650

4751
let reset_dump_state () =

compiler/ml/clflags.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ val dont_write_files : bool ref
2525
val keep_locs : bool ref
2626
val only_parse : bool ref
2727
val ignore_parse_errors : bool ref
28+
val editor_mode : bool ref
2829

2930
val parse_color_setting : string -> Misc.Color.setting option
3031
val color : Misc.Color.setting option ref

compiler/ml/predef.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ and ident_promise = ident_create "promise"
6565

6666
and ident_uncurried = ident_create "function$"
6767

68+
and ident_tainted = ident_create "tainted$"
69+
6870
type test = For_sure_yes | For_sure_no | NA
6971

7072
let type_is_builtin_path_but_option (p : Path.t) : test =
@@ -112,6 +114,8 @@ and path_promise = Pident ident_promise
112114

113115
and path_uncurried = Pident ident_uncurried
114116

117+
and path_tainted = Pident ident_tainted
118+
115119
let type_int = newgenty (Tconstr (path_int, [], ref Mnil))
116120

117121
and type_char = newgenty (Tconstr (path_char, [], ref Mnil))

compiler/ml/predef.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ val path_lazy_t : Path.t
5252
val path_extension_constructor : Path.t
5353
val path_promise : Path.t
5454
val path_uncurried : Path.t
55+
val path_tainted : Path.t
5556

5657
val path_match_failure : Path.t
5758
val path_assert_failure : Path.t

compiler/ml/typecore.ml

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ exception Error_forward of Location.error
8484

8585
(* Forward declaration, to be filled in by Typemod.type_module *)
8686

87+
let delayed_typechecking_errors = ref []
88+
89+
let add_delayed_error e =
90+
delayed_typechecking_errors := e :: !delayed_typechecking_errors
91+
92+
let get_first_delayed_error () =
93+
List.nth_opt (!delayed_typechecking_errors |> List.rev) 0
94+
8795
let type_module =
8896
ref
8997
(fun _env _md -> assert false
@@ -264,6 +272,18 @@ let option_none ty loc =
264272
let cnone = Env.lookup_constructor lid env in
265273
mkexp (Texp_construct (mknoloc lid, cnone, [])) ty loc env
266274

275+
let tainted () =
276+
let lid = Longident.Lident "None" and env = Env.initial_safe_string in
277+
let cnone = Env.lookup_constructor lid env in
278+
{
279+
exp_desc = Texp_construct (mknoloc lid, cnone, []);
280+
exp_type = newconstr Predef.path_tainted [];
281+
exp_loc = Location.none;
282+
exp_env = env;
283+
exp_extra = [];
284+
exp_attributes = [(Location.mknoloc "tainted", PStr [])];
285+
}
286+
267287
let option_some texp =
268288
let lid = Longident.Lident "Some" in
269289
let csome = Env.lookup_constructor lid Env.initial_safe_string in
@@ -2249,6 +2269,11 @@ and type_expect ?type_clash_context ?in_function ?recarg env sexp ty_expected =
22492269
in
22502270
Cmt_format.set_saved_types
22512271
(Cmt_format.Partial_expression exp :: previous_saved_types);
2272+
2273+
(match get_first_delayed_error () with
2274+
| None -> ()
2275+
| Some e -> raise e);
2276+
22522277
exp
22532278
22542279
and type_expect_ ?type_clash_context ?in_function ?(recarg = Rejected) env sexp
@@ -3537,7 +3562,15 @@ and type_application ?type_clash_context total_app env funct (sargs : sargs) :
35373562
( List.map
35383563
(function
35393564
| l, None -> (l, None)
3540-
| l, Some f -> (l, Some (f ())))
3565+
| l, Some f ->
3566+
( l,
3567+
Some
3568+
(if !Clflags.editor_mode then (
3569+
try f ()
3570+
with e ->
3571+
add_delayed_error e;
3572+
tainted ())
3573+
else f ()) ))
35413574
(List.rev args),
35423575
instance env (result_type omitted ty_fun) )
35433576
in

0 commit comments

Comments
 (0)