Skip to content

Commit 6a76c51

Browse files
committed
clean up super_error
1 parent 2bd9366 commit 6a76c51

24 files changed

+499
-895
lines changed

jscomp/bsc/dune

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,4 @@
88
(public_name bsc)
99
(flags
1010
(:standard -w +a-4-9-30-40-41-42-48-70))
11-
(libraries common core depends gentype js_parser syntax super_errors
12-
outcome_printer))
11+
(libraries common core depends gentype js_parser syntax outcome_printer))

jscomp/bsc/rescript_compiler_main.ml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ let setup_compiler_printer (syntax_kind : [ syntax_kind | `default])=
2525
| `default -> ()
2626
| #syntax_kind as k -> Config.syntax_kind := k);
2727
let syntax_kind = !Config.syntax_kind in
28-
if syntax_kind = `rescript then begin
29-
Lazy.force Super_main.setup;
28+
if syntax_kind = `rescript then begin
3029
Lazy.force Res_outcome_printer.setup
3130
end
3231

@@ -206,7 +205,6 @@ let print_version_string () =
206205

207206
let [@inline] set s : Bsc_args.spec = Unit (Unit_set s)
208207
let [@inline] clear s : Bsc_args.spec = Unit (Unit_clear s)
209-
let [@inline] unit_lazy s : Bsc_args.spec = Unit(Unit_lazy s)
210208
let [@inline] string_call s : Bsc_args.spec =
211209
String (String_call s)
212210
let [@inline] string_optional_set s : Bsc_args.spec =
@@ -294,10 +292,6 @@ let buckle_script_flags : (string * Bsc_args.spec * string) array =
294292

295293
(******************************************************************************)
296294

297-
298-
"-bs-super-errors", unit_lazy Super_main.setup,
299-
"*internal* Better error message combined with other tools ";
300-
301295
"-unboxed-types", set Clflags.unboxed_types,
302296
"*internal* Unannotated unboxable types will be unboxed";
303297

jscomp/build_tests/super_errors/input.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ let atLeastOneTaskFailed = false
2727

2828
fixtures.forEach(fileName => {
2929
const fullFilePath = path.join(__dirname, 'fixtures', fileName)
30-
const command = `${prefix} -color always -bs-super-errors ${fullFilePath}`
30+
const command = `${prefix} -color always ${fullFilePath}`
3131
console.log(`running ${command}`)
3232
child_process.exec(command, (err, stdout, stderr) => {
3333
doneTasksCount++

jscomp/gentype_tests/typescript-react-example/bsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"exportInterfaces": false
1616
},
1717
"name": "sample-typescript-app",
18-
"bsc-flags": ["-bs-super-errors"],
18+
"bsc-flags": [],
1919
"jsx": { "version": 3 },
2020
"bs-dependencies": ["@rescript/react"],
2121
"sources": [
File renamed without changes.

jscomp/ml/env.ml

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2276,32 +2276,42 @@ let env_of_only_summary env_from_summary env =
22762276

22772277
open Format
22782278

2279+
(* taken from https://github.com/rescript-lang/ocaml/blob/d4144647d1bf9bc7dc3aadc24c25a7efa3a67915/typing/env.ml#L1842 *)
2280+
(* modified branches are commented *)
22792281
let report_error ppf = function
2280-
| Illegal_renaming(modname, ps_name, filename) -> fprintf ppf
2281-
"Wrong file naming: %a@ contains the compiled interface for @ \
2282-
%s when %s was expected"
2283-
Location.print_filename filename ps_name modname
2284-
| Inconsistent_import(name, source1, source2) -> fprintf ppf
2282+
| Illegal_renaming(name, modname, _filename) ->
2283+
(* modified *)
2284+
fprintf ppf
2285+
"@[You referred to the module %s, but we've found one called %s instead.@ \
2286+
Is the name's casing right?@]"
2287+
name modname
2288+
| Inconsistent_import(name, source1, source2) ->
2289+
(* modified *)
2290+
fprintf ppf "@[<v>\
2291+
@[@{<info>It's possible that your build is stale.@}@ Try to clean the artifacts and build again?@]@,@,\
2292+
@[@{<info>Here's the original error message@}@]@,\
2293+
@]";
2294+
fprintf ppf
22852295
"@[<hov>The files %a@ and %a@ \
2286-
make inconsistent assumptions@ over interface %s@]"
2296+
make inconsistent assumptions@ over interface %s@]"
22872297
Location.print_filename source1 Location.print_filename source2 name
22882298
| Need_recursive_types(import, export) ->
2289-
fprintf ppf
2290-
"@[<hov>Unit %s imports from %s, which uses recursive types.@ %s@]"
2291-
export import "The compilation flag -rectypes is required"
2299+
fprintf ppf
2300+
"@[<hov>Unit %s imports from %s, which uses recursive types.@ %s@]"
2301+
export import "The compilation flag -rectypes is required"
22922302
| Missing_module(_, path1, path2) ->
2293-
fprintf ppf "@[@[<hov>";
2294-
if Path.same path1 path2 then
2295-
fprintf ppf "Internal path@ %s@ is dangling." (Path.name path1)
2296-
else
2297-
fprintf ppf "Internal path@ %s@ expands to@ %s@ which is dangling."
2298-
(Path.name path1) (Path.name path2);
2299-
fprintf ppf "@]@ @[%s@ %s@ %s.@]@]"
2300-
"The compiled interface for module" (Ident.name (Path.head path2))
2301-
"was not found"
2303+
fprintf ppf "@[@[<hov>";
2304+
if Path.same path1 path2 then
2305+
fprintf ppf "Internal path@ %s@ is dangling." (Path.name path1)
2306+
else
2307+
fprintf ppf "Internal path@ %s@ expands to@ %s@ which is dangling."
2308+
(Path.name path1) (Path.name path2);
2309+
fprintf ppf "@]@ @[%s@ %s@ %s.@]@]"
2310+
"The compiled interface for module" (Ident.name (Path.head path2))
2311+
"was not found"
23022312
| Illegal_value_name(_loc, name) ->
2303-
fprintf ppf "'%s' is not a valid value identifier."
2304-
name
2313+
fprintf ppf "'%s' is not a valid value identifier."
2314+
name
23052315

23062316
let () =
23072317
Location.register_error_of_exn

jscomp/ml/lexer.mll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ let report_error ppf = function
254254
| Unterminated_string_in_comment (_, loc) ->
255255
fprintf ppf "This comment contains an unterminated string literal@.\
256256
%aString literal begins here"
257-
Location.print_error loc
257+
(Location.print_error "") loc
258258
| Keyword_as_label kwd ->
259259
fprintf ppf "`%s' is a keyword, it cannot be used as label name" kwd
260260
| Invalid_literal s ->

jscomp/ml/location.ml

Lines changed: 117 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -104,40 +104,114 @@ let print_filename ppf file =
104104
let reset () =
105105
num_loc_lines := 0
106106

107-
let (msg_file, msg_line, msg_chars, msg_to, msg_colon) =
108-
("File \"", "\", line ", ", characters ", "-", ":")
109-
110107
(* return file, line, char from the given position *)
111108
let get_pos_info pos =
112109
(pos.pos_fname, pos.pos_lnum, pos.pos_cnum - pos.pos_bol)
113110
;;
114111

115112
let setup_colors () =
116-
Misc.Color.setup !Clflags.color
117-
118-
let print_loc ppf loc =
113+
Misc.Color.setup !Clflags.color;
114+
Code_frame.setup !Clflags.color
115+
116+
(* ocaml's reported line/col numbering is horrible and super error-prone
117+
when being handled programmatically (or humanly for that matter. If you're
118+
an ocaml contributor reading this: who the heck reads the character count
119+
starting from the first erroring character?) *)
120+
let normalize_range loc =
121+
(* TODO: lots of the handlings here aren't needed anymore because the new
122+
rescript syntax has much stronger invariants regarding positions, e.g.
123+
no -1 *)
124+
let (_, start_line, start_char) = get_pos_info loc.loc_start in
125+
let (_, end_line, end_char) = get_pos_info loc.loc_end in
126+
(* line is 1-indexed, column is 0-indexed. We convert all of them to 1-indexed to avoid confusion *)
127+
(* start_char is inclusive, end_char is exclusive *)
128+
if start_char == -1 || end_char == -1 then
129+
(* happens sometimes. Syntax error for example *)
130+
None
131+
else if start_line = end_line && start_char >= end_char then
132+
(* in some errors, starting char and ending char can be the same. But
133+
since ending char was supposed to be exclusive, here it might end up
134+
smaller than the starting char if we naively did start_char + 1 to
135+
just the starting char and forget ending char *)
136+
let same_char = start_char + 1 in
137+
Some ((start_line, same_char), (end_line, same_char))
138+
else
139+
(* again: end_char is exclusive, so +1-1=0 *)
140+
Some ((start_line, start_char + 1), (end_line, end_char))
141+
142+
let print_loc ppf (loc : t) =
119143
setup_colors ();
120-
let (file, line, startchar) = get_pos_info loc.loc_start in
121-
let startchar = startchar + 1 in
122-
let endchar = loc.loc_end.pos_cnum - loc.loc_start.pos_cnum + startchar in
123-
begin
124-
fprintf ppf "%s@{<loc>%a%s%i" msg_file print_filename file msg_line line;
125-
if startchar >= 0 then
126-
fprintf ppf "%s%i%s%i" msg_chars startchar msg_to endchar;
127-
fprintf ppf "@}"
128-
end
144+
let normalized_range = normalize_range loc in
145+
let dim_loc ppf = function
146+
| None -> ()
147+
| Some ((start_line, start_line_start_char), (end_line, end_line_end_char)) ->
148+
if start_line = end_line then
149+
if start_line_start_char = end_line_end_char then
150+
fprintf ppf ":@{<dim>%i:%i@}" start_line start_line_start_char
151+
else
152+
fprintf ppf ":@{<dim>%i:%i-%i@}" start_line start_line_start_char end_line_end_char
153+
else
154+
fprintf ppf ":@{<dim>%i:%i-%i:%i@}" start_line start_line_start_char end_line end_line_end_char
155+
in
156+
fprintf ppf "@{<filename>%a@}%a" print_filename loc.loc_start.pos_fname dim_loc normalized_range
129157
;;
130158

131-
let default_printer ppf loc =
132-
setup_colors ();
133-
fprintf ppf "@{<loc>%a@}%s@," print_loc loc msg_colon
159+
let print ~message_kind intro ppf (loc : t) =
160+
begin match message_kind with
161+
| `warning -> fprintf ppf "@[@{<info>%s@}@]@," intro
162+
| `warning_as_error -> fprintf ppf "@[@{<error>%s@} (configured as error) @]@," intro
163+
| `error -> fprintf ppf "@[@{<error>%s@}@]@," intro
164+
end;
165+
(* ocaml's reported line/col numbering is horrible and super error-prone
166+
when being handled programmatically (or humanly for that matter. If you're
167+
an ocaml contributor reading this: who the heck reads the character count
168+
starting from the first erroring character?) *)
169+
let (file, start_line, start_char) = get_pos_info loc.loc_start in
170+
let (_, end_line, end_char) = get_pos_info loc.loc_end in
171+
(* line is 1-indexed, column is 0-indexed. We convert all of them to 1-indexed to avoid confusion *)
172+
(* start_char is inclusive, end_char is exclusive *)
173+
let normalizedRange =
174+
(* TODO: lots of the handlings here aren't needed anymore because the new
175+
rescript syntax has much stronger invariants regarding positions, e.g.
176+
no -1 *)
177+
if start_char == -1 || end_char == -1 then
178+
(* happens sometimes. Syntax error for example *)
179+
None
180+
else if start_line = end_line && start_char >= end_char then
181+
(* in some errors, starting char and ending char can be the same. But
182+
since ending char was supposed to be exclusive, here it might end up
183+
smaller than the starting char if we naively did start_char + 1 to
184+
just the starting char and forget ending char *)
185+
let same_char = start_char + 1 in
186+
Some ((start_line, same_char), (end_line, same_char))
187+
else
188+
(* again: end_char is exclusive, so +1-1=0 *)
189+
Some ((start_line, start_char + 1), (end_line, end_char))
190+
in
191+
fprintf ppf " @[%a@]@," print_loc loc;
192+
match normalizedRange with
193+
| None -> ()
194+
| Some _ -> begin
195+
try
196+
let src = Ext_io.load_file file in
197+
(* we're putting the line break `@,` here rather than above, because this
198+
branch might not be reached (aka no inline file content display) so
199+
we don't wanna end up with two line breaks in the the consequent *)
200+
fprintf ppf "@,%s"
201+
(Code_frame.print
202+
~is_warning:(message_kind=`warning)
203+
~src
204+
~startPos:loc.loc_start
205+
~endPos:loc.loc_end
206+
)
207+
with
208+
(* this might happen if the file is e.g. "", "_none_" or any of the fake file name placeholders.
209+
we've already printed the location above, so nothing more to do here. *)
210+
| Sys_error _ -> ()
211+
end
134212
;;
135213

136-
let printer = ref default_printer
137-
let print ppf loc = !printer ppf loc
138-
139214
let error_prefix = "Error"
140-
let warning_prefix = "Warning"
141215

142216
let print_error_prefix ppf =
143217
setup_colors ();
@@ -153,30 +227,22 @@ let print_compact ppf loc =
153227
end
154228
;;
155229

156-
let print_error ppf loc =
157-
fprintf ppf "%a%t:" print loc print_error_prefix;
230+
let print_error intro ppf loc =
231+
fprintf ppf "%a%t:" (print ~message_kind:`error intro) loc print_error_prefix;
158232
;;
159233

160-
let print_error_cur_file ppf () = print_error ppf (in_file !input_name);;
161-
162234
let default_warning_printer loc ppf w =
163235
match Warnings.report w with
164236
| `Inactive -> ()
165-
| `Active { Warnings. number; message; is_error; sub_locs } ->
237+
| `Active { Warnings. number = _; message = _; is_error; sub_locs = _} ->
166238
setup_colors ();
167-
fprintf ppf "@[<v>";
168-
print ppf loc;
169-
if is_error
170-
then
171-
fprintf ppf "%t (%s %d): %s@," print_error_prefix
172-
(String.uncapitalize_ascii warning_prefix) number message
173-
else fprintf ppf "@{<warning>%s@} %d: %s@," warning_prefix number message;
174-
List.iter
175-
(fun (loc, msg) ->
176-
if loc <> none then fprintf ppf " %a %s@," print loc msg
177-
)
178-
sub_locs;
179-
fprintf ppf "@]"
239+
let message_kind = if is_error then `warning_as_error else `warning in
240+
Format.fprintf ppf "@[<v>@, %a@, %s@,@]@."
241+
(print ~message_kind ("Warning number " ^ (Warnings.number w |> string_of_int)))
242+
loc
243+
(Warnings.message w);
244+
(* at this point, you can display sub_locs too, from e.g. https://github.com/ocaml/ocaml/commit/f6d53cc38f87c67fbf49109f5fb79a0334bab17a
245+
but we won't bother for now *)
180246
;;
181247

182248
let warning_printer = ref default_warning_printer ;;
@@ -225,10 +291,13 @@ let pp_ksprintf ?before k fmt =
225291
k msg)
226292
ppf fmt
227293

294+
(* taken from https://github.com/rescript-lang/ocaml/blob/d4144647d1bf9bc7dc3aadc24c25a7efa3a67915/parsing/location.ml#L354 *)
228295
(* Shift the formatter's offset by the length of the error prefix, which
229296
is always added by the compiler after the message has been formatted *)
230297
let print_phanton_error_prefix ppf =
231-
Format.pp_print_as ppf (String.length error_prefix + 2 (* ": " *)) ""
298+
(* modified from the original. We use only 2 indentations for error report
299+
(see super_error_reporter above) *)
300+
Format.pp_print_as ppf 2 ""
232301

233302
let errorf ?(loc = none) ?(sub = []) ?(if_highlight = "") fmt =
234303
pp_ksprintf
@@ -258,11 +327,14 @@ let error_of_exn exn =
258327
in
259328
loop !error_of_exn
260329

261-
330+
(* taken from https://github.com/rescript-lang/ocaml/blob/d4144647d1bf9bc7dc3aadc24c25a7efa3a67915/parsing/location.ml#L380 *)
331+
(* This is the error report entry point. We'll replace the default reporter with this one. *)
262332
let rec default_error_reporter ppf ({loc; msg; sub}) =
263-
fprintf ppf "@[<v>%a %s" print_error loc msg;
264-
List.iter (Format.fprintf ppf "@,@[<2>%a@]" default_error_reporter) sub;
265-
fprintf ppf "@]"
333+
setup_colors ();
334+
(* open a vertical box. Everything in our message is indented 2 spaces *)
335+
Format.fprintf ppf "@[<v>@, %a@, %s@,@]" (print ~message_kind:`error "We've found a bug for you!") loc msg;
336+
List.iter (Format.fprintf ppf "@,@[%a@]" default_error_reporter) sub
337+
(* no need to flush here; location's report_exception (which uses this ultimately) flushes *)
266338

267339
let error_reporter = ref default_error_reporter
268340

jscomp/ml/location.mli

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,12 @@ val input_lexbuf: Lexing.lexbuf option ref
5656

5757
val get_pos_info: Lexing.position -> string * int * int (* file, line, char *)
5858
val print_loc: formatter -> t -> unit
59-
val print_error: formatter -> t -> unit
60-
val print_error_cur_file: formatter -> unit -> unit
59+
val print_error: tag -> formatter -> t -> unit
6160

6261
val prerr_warning: t -> Warnings.t -> unit
6362
val echo_eof: unit -> unit
6463
val reset: unit -> unit
6564

66-
val default_printer : formatter -> t -> unit
67-
val printer : (formatter -> t -> unit) ref
68-
6965
val warning_printer : (t -> formatter -> Warnings.t -> unit) ref
7066
(** Hook for intercepting warnings. *)
7167

@@ -82,7 +78,7 @@ type 'a loc = {
8278
val mknoloc : 'a -> 'a loc
8379
val mkloc : 'a -> t -> 'a loc
8480

85-
val print: formatter -> t -> unit
81+
val print: message_kind:[< `error | `warning | `warning_as_error > `warning] -> string -> formatter -> t -> unit
8682
val print_compact: formatter -> t -> unit
8783
val print_filename: formatter -> string -> unit
8884

0 commit comments

Comments
 (0)