• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Kakadu / zanuda / 18

17 Sep 2025 05:06PM UTC coverage: 85.847% (-1.5%) from 87.346%
18

push

github

Kakadu
Repair coverage testing

Signed-off-by: Kakadu <Kakadu@pm.me>

2032 of 2367 relevant lines covered (85.85%)

477.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.83
/src/typed/Propose_function.ml
1
[@@@ocaml.text "/*"]
2

3
(** Copyright 2021-2025, Kakadu. *)
4

5
(** SPDX-License-Identifier: LGPL-3.0-or-later *)
6

7
[@@@ocaml.text "/*"]
8

9
open Base
10
open Zanuda_core
11
open Zanuda_core.Utils
12

13
type input = Tast_iterator.iterator
14

15
let lint_id = "propose_function"
16
let lint_source = LINT.FPCourse
17
let group = LINT.Style
18
let level = LINT.Warn
19

20
let documentation =
21
  {|
22
### What it does
23
Proposes to rewrite 'fun x -> match x with ...' to `function`.
24

25
### Why?
26
The `function` keyword allows more shorter syntax for pattern matching on last argument.
27
The lint should not be raised if scrutinee variable is used later in the code.
28

29
The following code is recommended:
30

31
```ocaml
32
  let f = function
33
    | [] -> ...
34
    | (x::xs) as arg -> ... x ... xs ... arg
35
```
36

37
And this piece of code is discouraged:
38

39
```ocaml
40
  let f arg  = match arg with
41
    | [] -> ...
42
    | (x::xs) -> ... x ... xs ... arg
43
```
44
|}
45
  |> Stdlib.String.trim
48✔
46
;;
47

48
let describe_as_json () =
49
  describe_as_clippy_json lint_id ~group ~level ~docs:documentation
1✔
50
;;
51

52
let msg ppf () = Format.fprintf ppf "Using `function` is recommended%!"
12✔
53

54
let report filename ~loc =
55
  let module M = struct
9✔
56
    let txt ppf () = Utils.Report.txt ~filename ~loc ppf msg ()
9✔
57

58
    let rdjsonl ppf () =
59
      RDJsonl.pp
3✔
60
        ppf
61
        ~filename:(Config.recover_filepath loc.loc_start.pos_fname)
3✔
62
        ~line:loc.loc_start.pos_lnum
63
        msg
64
        ()
65
    ;;
66
  end
67
  in
68
  (module M : LINT.REPORTER)
69
;;
70

71
let no_ident ident c = Utils.no_ident ident (fun it -> it.case it c)
21✔
72

73
let pat () =
74
  let open Tast_pattern in
1,320✔
75
  texp_function_body
76
    ((nolabel ** __) ^:: nil)
1,320✔
77
    (as__ (texp_match (texp_ident_loc __) drop __))
1,320✔
78
;;
79

80
let run _ fallback =
81
  let open Tast_iterator in
53✔
82
  { fallback with
83
    expr =
84
      (fun self expr ->
85
        let open Typedtree in
1,320✔
86
        let loc = expr.exp_loc in
87
        Tast_pattern.parse
88
          (pat ())
1,320✔
89
          loc
90
          ~on_error:(fun _desc () -> ())
1,309✔
91
          expr
92
          (fun (scru_ident, scru_loc) match_expr _scru_loc scru_pat cases () ->
93
            match scru_pat with
11✔
94
            | Path.Pident id ->
11✔
95
              if String.equal (Ident.name scru_ident) (Ident.name id)
11✔
96
                 && List.for_all cases ~f:(no_ident scru_ident)
10✔
97
              then (
9✔
98
                Collected_lints.add
99
                  ~loc
100
                  (report loc.Location.loc_start.Lexing.pos_fname ~loc);
9✔
101
                Refactoring.Propose_function.register_fix
9✔
102
                  ~loc:match_expr.exp_loc
103
                  scru_loc
104
                  cases)
105
            | _ -> ())
×
106
          ();
107
        fallback.expr self expr)
1,320✔
108
  }
109
;;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc