swh:1:snp:9f9174fb54ac68d4510837c2f930cf0558bce5b6
Tip revision: b9c76857753141848129e5029c7921eae83bda06 authored by Christian Doczkal on 03 November 2021, 15:28:23 UTC
comments, renaming, proof*
comments, renaming, proof*
Tip revision: b9c7685
ppx_lint.ml
(* -------------------------------------------------------------------- *)
open Ast_mapper
open Parsetree
(* -------------------------------------------------------------------- *)
type error =
| CatchAllInTryWith
| CatchAllInMatch
exception Error of Location.t * error
(* -------------------------------------------------------------------- *)
let string_of_error = function
| CatchAllInTryWith -> "catch all in try...with..."
| CatchAllInMatch -> "catch all in match...with"
(* -------------------------------------------------------------------- *)
let error_of_exn = function
| Error (loc, error) ->
Some (Location.error ~loc (string_of_error error))
| _ -> None
(* -------------------------------------------------------------------- *)
let () = Location.register_error_of_exn error_of_exn
(* -------------------------------------------------------------------- *)
let rec is_wild_pattern (p : pattern) =
match p.ppat_desc with
| Ppat_any -> true
| Ppat_var _ -> true
| Ppat_alias (p, _) ->
is_wild_pattern p
| Ppat_or (p1, p2) ->
is_wild_pattern p1 || is_wild_pattern p2
| Ppat_constraint (p, _) ->
is_wild_pattern p
| Ppat_extension ({ Asttypes.txt = "catchall" }, _) ->
false
| Ppat_extension (_, PPat (p, _)) ->
is_wild_pattern p
| _ -> false
(* -------------------------------------------------------------------- *)
let is_wild_case (c : case) =
is_wild_pattern c.pc_lhs
(* -------------------------------------------------------------------- *)
let rec catchall_mapper =
{ default_mapper with
expr = fun mapper expr ->
match expr.pexp_desc with
| Pexp_try (e, clauses) ->
if List.exists is_wild_case clauses then
Format.eprintf "Lint: %a %s\n%!"
Location.print_loc expr.pexp_loc
(string_of_error CatchAllInTryWith);
let e = catchall_mapper.expr mapper e in
let clauses = catchall_mapper.cases mapper clauses in
{ expr with pexp_desc = Pexp_try (e, clauses) }
| _ -> default_mapper.expr mapper expr }
(* -------------------------------------------------------------------- *)
let () = register "catchall" (fun _ -> catchall_mapper)