this repo has no description
at main 87 lines 2.5 kB view raw
1open Odoc_model 2 3type context = { c_loc : Location_.span option; c_context : string list } 4(** Context added by {!with_location} and {!with_context}. *) 5 6let context_acc = ref { c_loc = None; c_context = [] } 7 8let acc = ref [] 9 10let with_ref r x f = 11 let saved = !r in 12 r := x; 13 let v = f () in 14 let x = !r in 15 r := saved; 16 (v, x) 17 18let add f = acc := f :: !acc 19 20(** Raise a single message for root errors. *) 21let raise_root_errors ~filename failures = 22 let roots = 23 List.fold_left 24 (fun acc -> function `Root name -> name :: acc | `Warning _ -> acc) 25 [] failures 26 |> List.sort_uniq String.compare 27 in 28 match roots with 29 | [] -> () 30 | _ :: _ -> 31 Error.raise_warning ~non_fatal:true 32 (Error.filename_only "Couldn't find the following modules:@;<1 2>@[%a@]" 33 Format.(pp_print_list ~pp_sep:pp_print_space pp_print_string) 34 roots filename) 35 36(** Raise the other warnings. *) 37let raise_warnings ~filename failures = 38 List.iter 39 (function 40 | `Root _ -> () 41 | `Warning (msg, context, non_fatal) -> 42 let rec pp_context fmt = function 43 | hd :: tl -> 44 pp_context fmt tl; 45 Format.fprintf fmt "%s@\n" hd 46 | [] -> () 47 in 48 let pp_failure fmt () = 49 Format.fprintf fmt "%a%s" pp_context context.c_context msg 50 in 51 let err = 52 match context.c_loc with 53 | Some loc -> Error.make "%a" pp_failure () loc 54 | None -> Error.filename_only "%a" pp_failure () filename 55 in 56 Error.raise_warning ~non_fatal err) 57 failures 58 59let catch_failures ~filename f = 60 let r, failures = with_ref acc [] f in 61 Error.catch_warnings (fun () -> 62 if !Error.enable_missing_root_warning then 63 raise_root_errors ~filename failures; 64 raise_warnings ~filename failures; 65 r) 66 67let kasprintf k fmt = 68 Format.(kfprintf (fun _ -> k (flush_str_formatter ())) str_formatter fmt) 69 70let report ~non_fatal fmt = 71 kasprintf (fun msg -> add (`Warning (msg, !context_acc, non_fatal))) fmt 72 73let report_internal fmt = report ~non_fatal:true fmt 74 75let report_root ~name = add (`Root name) 76 77let report_warning fmt = report ~non_fatal:false fmt 78 79let with_location loc f = 80 fst (with_ref context_acc { !context_acc with c_loc = Some loc } f) 81 82let with_context fmt = 83 kasprintf 84 (fun msg f -> 85 let c = !context_acc in 86 fst (with_ref context_acc { c with c_context = msg :: c.c_context } f)) 87 fmt