report.ml 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. (** Report built over the differents analysis in the file *)
  2. type level = Error | Warn | Debug
  3. [@@deriving show { with_path = false }, enum, eq]
  4. type pos = Lexing.position * Lexing.position
  5. let level_of_string : string -> (level, string) result =
  6. fun level ->
  7. match String.lowercase_ascii level with
  8. | "error" -> Ok Error
  9. | "warn" -> Ok Warn
  10. | "debug" -> Ok Debug
  11. | _ ->
  12. Error
  13. (Format.sprintf
  14. "Unknown report level '%s'. Accepted values are error, warn, debug"
  15. level)
  16. let pp_pos : Format.formatter -> pos -> unit =
  17. fun f (start_pos, end_pos) ->
  18. let start_c = start_pos.Lexing.pos_cnum - start_pos.Lexing.pos_bol
  19. and end_c = end_pos.Lexing.pos_cnum - end_pos.Lexing.pos_bol
  20. and start_line = start_pos.Lexing.pos_lnum
  21. and end_line = end_pos.Lexing.pos_lnum in
  22. if start_line != end_line then
  23. Format.fprintf f "Lines %d-%d" start_line end_line
  24. else Format.fprintf f "Line %d %d:%d" start_line start_c end_c
  25. let pp_line : Format.formatter -> pos -> unit =
  26. fun f (start_pos, end_pos) ->
  27. (* Only care about the first line *)
  28. ignore end_pos;
  29. let start_line = start_pos.Lexing.pos_lnum in
  30. Format.fprintf f "%d" start_line
  31. type t = { level : level; loc : pos; message : string }
  32. [@@deriving show { with_path = false }]
  33. (** Compare two positions *)
  34. let compare_pos : pos -> pos -> int =
  35. fun (pos1_start, pos1_end) (pos2_start, pos2_end) ->
  36. (* first compare the position *)
  37. match compare pos1_start.pos_cnum pos2_start.pos_cnum with
  38. | 0 ->
  39. (* Then the ending position *)
  40. compare pos1_end.pos_cnum pos2_end.pos_cnum
  41. | other -> other
  42. let compare : t -> t -> int =
  43. fun t1 t2 ->
  44. (* first compare the position *)
  45. match compare_pos t1.loc t2.loc with
  46. | 0 -> (
  47. (* And the level *)
  48. match compare (level_to_enum t1.level) (level_to_enum t2.level) with
  49. | 0 -> String.compare t1.message t2.message
  50. | other -> other)
  51. | other -> other
  52. let debug : pos -> string -> t =
  53. fun loc message -> { level = Debug; loc; message }
  54. let warn : pos -> string -> t =
  55. fun loc message -> { level = Warn; loc; message }
  56. let error : pos -> string -> t =
  57. fun loc message -> { level = Error; loc; message }
  58. let message level loc message = { level; loc; message }
  59. type result = t list [@@deriving show]