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

Kakadu / zanuda / 27

18 Sep 2025 07:20AM UTC coverage: 86.255% (+0.01%) from 86.245%
27

push

github

Kakadu
Enable alpine and opensuse back

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

2209 of 2561 relevant lines covered (86.26%)

523.98 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
47✔
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%!"
10✔
53

54
let report filename ~loc =
55
  let module M = struct
7✔
56
    let txt ppf () = Utils.Report.txt ~filename ~loc ppf msg ()
7✔
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)
17✔
72

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

80
let run _ fallback =
81
  let open Tast_iterator in
52✔
82
  { fallback with
83
    expr =
84
      (fun self expr ->
85
        let open Typedtree in
1,246✔
86
        let loc = expr.exp_loc in
87
        Tast_pattern.parse
88
          (pat ())
1,246✔
89
          loc
90
          ~on_error:(fun _desc () -> ())
1,237✔
91
          expr
92
          (fun (scru_ident, scru_loc) match_expr _scru_loc scru_pat cases () ->
93
            match scru_pat with
9✔
94
            | Path.Pident id ->
9✔
95
              if
96
                String.equal (Ident.name scru_ident) (Ident.name id)
9✔
97
                && List.for_all cases ~f:(no_ident scru_ident)
8✔
98
              then (
7✔
99
                Collected_lints.add
100
                  ~loc
101
                  (report loc.Location.loc_start.Lexing.pos_fname ~loc);
7✔
102
                Refactoring.Propose_function.register_fix
7✔
103
                  ~loc:match_expr.exp_loc
104
                  scru_loc
105
                  cases)
106
            | _ -> ())
×
107
          ();
108
        fallback.expr self expr)
1,246✔
109
  }
110
;;
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