this repo has no description
at main 148 lines 4.3 kB view raw
1let enable_missing_root_warning = ref false 2 3type full_location_payload = Odoc_parser.Warning.t = { 4 location : Location_.span; 5 message : string; 6} 7 8type filename_only_payload = { file : string; message : string } 9 10type t = 11 [ `With_full_location of Odoc_parser.Warning.t 12 | `With_filename_only of filename_only_payload ] 13 14let kasprintf k fmt = 15 Format.(kfprintf (fun _ -> k (flush_str_formatter ())) str_formatter fmt) 16 17let kmake k ?suggestion format = 18 format 19 |> kasprintf (fun message -> 20 match suggestion with 21 | None -> k message 22 | Some suggestion -> k (message ^ "\nSuggestion: " ^ suggestion)) 23 24let make ?suggestion format = 25 let k message location = `With_full_location { location; message } in 26 kmake k ?suggestion format 27 28let filename_only ?suggestion format = 29 let k message file = `With_filename_only { file; message } in 30 kmake k ?suggestion format 31 32let _to_string = 33 let pp_prefix ppf = function 34 | Some p -> Format.fprintf ppf "%s: " p 35 | None -> () 36 in 37 fun ?prefix -> function 38 | `With_full_location { location; message } -> 39 if String.compare location.file "" != 0 then 40 Format.asprintf "%a:@\n%a%s" Location_.pp location pp_prefix prefix 41 message 42 else Format.asprintf "%a%s" pp_prefix prefix message 43 | `With_filename_only { file; message } -> 44 Format.asprintf "File \"%s\":@\n%a%s" file pp_prefix prefix message 45 46let to_string e = _to_string e 47 48exception Conveyed_by_exception of t 49 50let raise_exception error = raise (Conveyed_by_exception error) 51 52let catch f = try Ok (f ()) with Conveyed_by_exception error -> Error error 53 54type warning = { 55 w : t; 56 non_fatal : bool; 57 (** If [true], the warning won't be made fatal in [warn_error] mode. *) 58} 59 60type 'a with_warnings = { value : 'a; warnings : warning list } 61 62let with_ref r f = 63 let saved = !r in 64 try 65 let v = f () in 66 r := saved; 67 v 68 with e -> 69 r := saved; 70 raise e 71 72let raised_warnings = ref [] 73 74let raise_warnings' warnings = 75 raised_warnings := List.rev_append warnings !raised_warnings 76 77let raise_warning ?(non_fatal = false) w = 78 raised_warnings := { w; non_fatal } :: !raised_warnings 79 80let raise_warnings with_warnings = 81 raise_warnings' with_warnings.warnings; 82 with_warnings.value 83 84let catch_warnings f = 85 with_ref raised_warnings (fun () -> 86 raised_warnings := []; 87 let value = f () in 88 let warnings = List.rev !raised_warnings in 89 { value; warnings }) 90 91type 'a with_errors_and_warnings = ('a, t) result with_warnings 92 93let raise_errors_and_warnings we = 94 match raise_warnings we with Ok x -> x | Error e -> raise_exception e 95 96let catch_errors_and_warnings f = catch_warnings (fun () -> catch f) 97 98let print_error ?prefix t = prerr_endline (_to_string ?prefix t) 99 100let print_errors = List.iter print_error 101 102type warnings_options = { 103 warn_error : bool; 104 print_warnings : bool; 105 warnings_tag : string option; 106} 107 108let print_warnings ~warnings_options warnings = 109 if warnings_options.print_warnings then 110 List.iter 111 (fun w -> 112 let prefix = 113 if warnings_options.warn_error && not w.non_fatal then "Error" 114 else "Warning" 115 in 116 print_error ~prefix w.w) 117 warnings 118 119(* When there is warnings. *) 120let handle_warn_error ~warnings_options warnings ok = 121 print_warnings ~warnings_options warnings; 122 let maybe_fatal = List.exists (fun w -> not w.non_fatal) warnings in 123 if maybe_fatal && warnings_options.warn_error then 124 Error (`Msg "Warnings have been generated.") 125 else Ok ok 126 127let handle_warnings ~warnings_options ww = 128 handle_warn_error ~warnings_options ww.warnings ww.value 129 130let handle_errors_and_warnings ~warnings_options = function 131 | { value = Error e; warnings } -> 132 print_warnings ~warnings_options warnings; 133 Error (`Msg (to_string e)) 134 | { value = Ok ok; warnings } -> 135 handle_warn_error ~warnings_options warnings ok 136 137let unpack_warnings ww = (ww.value, List.map (fun w -> w.w) ww.warnings) 138 139let t_of_parser_t : Odoc_parser.Warning.t -> t = 140 fun x -> (`With_full_location x :> t) 141 142let raise_parser_warnings v = 143 (* Parsing errors may be fatal. *) 144 let warnings = Odoc_parser.warnings v in 145 let non_fatal = false in 146 raise_warnings' 147 (List.map (fun p -> { w = t_of_parser_t p; non_fatal }) warnings); 148 Odoc_parser.ast v