mirror of
https://github.com/CatalaLang/catala.git
synced 2024-11-08 07:51:43 +03:00
add lsp error notification mechanism
This commit is contained in:
parent
b80e453a2e
commit
c83e247d5d
@ -275,10 +275,10 @@ module Content = struct
|
|||||||
restore_ppf ();
|
restore_ppf ();
|
||||||
Format.pp_print_newline ppf ()
|
Format.pp_print_newline ppf ()
|
||||||
|
|
||||||
let emit ?(pp_marker = pp_marker) (content : t) (target : level) : unit =
|
let emit ?ppf ?(pp_marker = pp_marker) (content : t) (target : level) : unit =
|
||||||
|
let ppf = Option.value ~default:(get_ppf target) ppf in
|
||||||
match Global.options.message_format with
|
match Global.options.message_format with
|
||||||
| Global.Human -> (
|
| Global.Human -> (
|
||||||
let ppf = get_ppf target in
|
|
||||||
match target with
|
match target with
|
||||||
| Debug | Log -> basic_msg ~pp_marker ppf target content
|
| Debug | Log -> basic_msg ~pp_marker ppf target content
|
||||||
| Result | Warning | Error -> fancy_msg ~pp_marker ppf target content)
|
| Result | Warning | Error -> fancy_msg ~pp_marker ppf target content)
|
||||||
@ -288,7 +288,6 @@ module Content = struct
|
|||||||
message everywhere there is not a more precise message. If we can't
|
message everywhere there is not a more precise message. If we can't
|
||||||
find a position without a more precise message, we just take the first
|
find a position without a more precise message, we just take the first
|
||||||
position in the list to pair with the message. *)
|
position in the list to pair with the message. *)
|
||||||
let ppf = get_ppf target in
|
|
||||||
Format.pp_print_list ~pp_sep:Format.pp_print_newline
|
Format.pp_print_list ~pp_sep:Format.pp_print_newline
|
||||||
(fun ppf elt ->
|
(fun ppf elt ->
|
||||||
let pos, message =
|
let pos, message =
|
||||||
@ -327,10 +326,10 @@ module Content = struct
|
|||||||
ppf content;
|
ppf content;
|
||||||
Format.pp_print_newline ppf ()
|
Format.pp_print_newline ppf ()
|
||||||
|
|
||||||
let emit_n (target : level) = function
|
let emit_n ?ppf (target : level) = function
|
||||||
| [content] -> emit content target
|
| [content] -> emit content target
|
||||||
| contents ->
|
| contents ->
|
||||||
let ppf = get_ppf target in
|
let ppf = Option.value ~default:(get_ppf target) ppf in
|
||||||
let len = List.length contents in
|
let len = List.length contents in
|
||||||
List.iteri
|
List.iteri
|
||||||
(fun i c ->
|
(fun i c ->
|
||||||
@ -340,7 +339,7 @@ module Content = struct
|
|||||||
emit ~pp_marker c target)
|
emit ~pp_marker c target)
|
||||||
contents
|
contents
|
||||||
|
|
||||||
let emit (content : t) (target : level) = emit content target
|
let emit ?ppf (content : t) (target : level) = emit ?ppf content target
|
||||||
end
|
end
|
||||||
|
|
||||||
open Content
|
open Content
|
||||||
@ -350,6 +349,18 @@ open Content
|
|||||||
exception CompilerError of Content.t
|
exception CompilerError of Content.t
|
||||||
exception CompilerErrors of Content.t list
|
exception CompilerErrors of Content.t list
|
||||||
|
|
||||||
|
type lsp_error_kind = Lexing | Parsing | Typing | Generic
|
||||||
|
|
||||||
|
type lsp_error = {
|
||||||
|
kind : lsp_error_kind;
|
||||||
|
message : Format.formatter -> unit;
|
||||||
|
pos : Pos.t option;
|
||||||
|
suggestion : string list option;
|
||||||
|
}
|
||||||
|
|
||||||
|
let global_error_hook = ref None
|
||||||
|
let register_lsp_error_notifier f = global_error_hook := Some f
|
||||||
|
|
||||||
(** {1 Error printing} *)
|
(** {1 Error printing} *)
|
||||||
|
|
||||||
type ('a, 'b) emitter =
|
type ('a, 'b) emitter =
|
||||||
@ -425,7 +436,18 @@ let log = make ~level:Log ~cont:emit
|
|||||||
let result = make ~level:Result ~cont:emit
|
let result = make ~level:Result ~cont:emit
|
||||||
let results r = emit (List.flatten (List.map of_result r)) Result
|
let results r = emit (List.flatten (List.map of_result r)) Result
|
||||||
let warning = make ~level:Warning ~cont:emit
|
let warning = make ~level:Warning ~cont:emit
|
||||||
let error = make ~level:Error ~cont:(fun m _ -> raise (CompilerError m))
|
|
||||||
|
let error ?(kind = Generic) : ('a, 'exn) emitter =
|
||||||
|
fun ?header ?internal ?pos ?pos_msg ?extra_pos ?fmt_pos ?outcome ?suggestion
|
||||||
|
fmt ->
|
||||||
|
make ?header ?internal ?pos ?pos_msg ?extra_pos ?fmt_pos ?outcome ?suggestion
|
||||||
|
fmt ~level:Error ~cont:(fun m _ ->
|
||||||
|
Option.iter
|
||||||
|
(fun f ->
|
||||||
|
let message ppf = Content.emit ~ppf m Error in
|
||||||
|
f { kind; message; pos; suggestion })
|
||||||
|
!global_error_hook;
|
||||||
|
raise (CompilerError m))
|
||||||
|
|
||||||
(* Multiple errors handling *)
|
(* Multiple errors handling *)
|
||||||
|
|
||||||
@ -436,8 +458,16 @@ type global_errors = {
|
|||||||
|
|
||||||
let global_errors = { errors = None; stop_on_error = false }
|
let global_errors = { errors = None; stop_on_error = false }
|
||||||
|
|
||||||
let delayed_error x =
|
let delayed_error ?(kind = Generic) x : ('a, 'exn) emitter =
|
||||||
make ~level:Error ~cont:(fun m _ ->
|
fun ?header ?internal ?pos ?pos_msg ?extra_pos ?fmt_pos ?outcome ?suggestion
|
||||||
|
fmt ->
|
||||||
|
make ?header ?internal ?pos ?pos_msg ?extra_pos ?fmt_pos ?outcome ?suggestion
|
||||||
|
fmt ~level:Error ~cont:(fun m _ ->
|
||||||
|
Option.iter
|
||||||
|
(fun f ->
|
||||||
|
let message ppf = Content.emit ~ppf m Error in
|
||||||
|
f { kind; message; pos; suggestion })
|
||||||
|
!global_error_hook;
|
||||||
if global_errors.stop_on_error then raise (CompilerError m);
|
if global_errors.stop_on_error then raise (CompilerError m);
|
||||||
match global_errors.errors with
|
match global_errors.errors with
|
||||||
| None ->
|
| None ->
|
||||||
@ -458,15 +488,19 @@ let with_delayed_errors
|
|||||||
"delayed error called outside scope: encapsulate using \
|
"delayed error called outside scope: encapsulate using \
|
||||||
'with_delayed_errors' first");
|
'with_delayed_errors' first");
|
||||||
global_errors.stop_on_error <- stop_on_error;
|
global_errors.stop_on_error <- stop_on_error;
|
||||||
let r = f () in
|
try
|
||||||
match global_errors.errors with
|
let r = f () in
|
||||||
| None -> error ~internal:true "intertwined delayed error scope"
|
match global_errors.errors with
|
||||||
| Some [] ->
|
| None -> error ~internal:true "intertwined delayed error scope"
|
||||||
|
| Some [] ->
|
||||||
|
global_errors.errors <- None;
|
||||||
|
r
|
||||||
|
| Some [err] ->
|
||||||
|
global_errors.errors <- None;
|
||||||
|
raise (CompilerError err)
|
||||||
|
| Some errs ->
|
||||||
|
global_errors.errors <- None;
|
||||||
|
raise (CompilerErrors (List.rev errs))
|
||||||
|
with e ->
|
||||||
global_errors.errors <- None;
|
global_errors.errors <- None;
|
||||||
r
|
raise e
|
||||||
| Some [err] ->
|
|
||||||
global_errors.errors <- None;
|
|
||||||
raise (CompilerError err)
|
|
||||||
| Some errs ->
|
|
||||||
global_errors.errors <- None;
|
|
||||||
raise (CompilerErrors (List.rev errs))
|
|
||||||
|
@ -54,8 +54,8 @@ module Content : sig
|
|||||||
|
|
||||||
(** {2 Content emission}*)
|
(** {2 Content emission}*)
|
||||||
|
|
||||||
val emit : t -> level -> unit
|
val emit_n : ?ppf:Format.formatter -> level -> t list -> unit
|
||||||
val emit_n : level -> t list -> unit
|
val emit : ?ppf:Format.formatter -> t -> level -> unit
|
||||||
end
|
end
|
||||||
|
|
||||||
(** This functions emits the message according to the emission type defined by
|
(** This functions emits the message according to the emission type defined by
|
||||||
@ -66,6 +66,17 @@ end
|
|||||||
exception CompilerError of Content.t
|
exception CompilerError of Content.t
|
||||||
exception CompilerErrors of Content.t list
|
exception CompilerErrors of Content.t list
|
||||||
|
|
||||||
|
type lsp_error_kind = Lexing | Parsing | Typing | Generic
|
||||||
|
|
||||||
|
type lsp_error = {
|
||||||
|
kind : lsp_error_kind;
|
||||||
|
message : Content.message;
|
||||||
|
pos : Pos.t option;
|
||||||
|
suggestion : string list option;
|
||||||
|
}
|
||||||
|
|
||||||
|
val register_lsp_error_notifier : (lsp_error -> unit) -> unit
|
||||||
|
|
||||||
(** {1 Some formatting helpers}*)
|
(** {1 Some formatting helpers}*)
|
||||||
|
|
||||||
val unformat : (Format.formatter -> unit) -> string
|
val unformat : (Format.formatter -> unit) -> string
|
||||||
@ -105,7 +116,7 @@ val log : ('a, unit) emitter
|
|||||||
val debug : ('a, unit) emitter
|
val debug : ('a, unit) emitter
|
||||||
val result : ('a, unit) emitter
|
val result : ('a, unit) emitter
|
||||||
val warning : ('a, unit) emitter
|
val warning : ('a, unit) emitter
|
||||||
val error : ('a, 'exn) emitter
|
val error : ?kind:lsp_error_kind -> ('a, 'exn) emitter
|
||||||
val results : Content.message list -> unit
|
val results : Content.message list -> unit
|
||||||
|
|
||||||
(** Multiple errors *)
|
(** Multiple errors *)
|
||||||
@ -119,4 +130,4 @@ val with_delayed_errors : ?stop_on_error:bool -> (unit -> 'a) -> 'a
|
|||||||
@raise CompilerError
|
@raise CompilerError
|
||||||
on the first error encountered when the [stop_on_error] flag is set. *)
|
on the first error encountered when the [stop_on_error] flag is set. *)
|
||||||
|
|
||||||
val delayed_error : 'b -> ('a, 'b) emitter
|
val delayed_error : ?kind:lsp_error_kind -> 'b -> ('a, 'b) emitter
|
||||||
|
Loading…
Reference in New Issue
Block a user