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

Kakadu / zanuda / 35

04 Oct 2025 04:11PM UTC coverage: 86.659% (+0.4%) from 86.294%
35

push

github

Kakadu
Enable/disable test on libraries availability

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

2215 of 2556 relevant lines covered (86.66%)

525.88 hits per line

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

77.19
/src/pattern/Tast_pattern.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
module Ast_pattern0 = struct
10
  exception Expected of Location.t * string
11

12
  let fail loc expected = raise (Expected (loc, expected))
70,179✔
13

14
  type context =
15
    { (* [matched] counts how many constructors have been matched. This is used to find what
16
         pattern matches the most some piece of ast in [Ast_pattern.alt]. In the case where
17
         all branches fail to match, we report the error from the one that matches the
18
         most.
19
         This is only incremented by combinators that can fail. *)
20
      mutable matched : int
21
    }
22

23
  type ('matched_value, 'k, 'k_result) t =
24
    | T of (context -> Location.t -> 'matched_value -> 'k -> 'k_result)
25

26
  (* end of copy-paste from https://github.com/ocaml-ppx/ppxlib/blob/0.22.2/src/ast_pattern0.ml *)
27
  (* TODO: deal with licencing issues *)
28
end
29

30
open Location
31
open Format
32
open Ast_pattern0
33

34
let debug_enabled = false
35

36
let log fmt =
37
  let open Format in
1,203✔
38
  if debug_enabled then kasprintf (printf "%s\n%!") fmt else ifprintf std_formatter fmt
×
39
;;
40

41
type ('a, 'b, 'c) t = ('a, 'b, 'c) Ast_pattern0.t
42

43
let save_context ctx = ctx.matched
123,276✔
44
let restore_context ctx backup = ctx.matched <- backup
81,058✔
45
let incr_matched c = c.matched <- c.matched + 1
4,076✔
46

47
let parse (T f) loc ?on_error x k =
48
  try f { matched = 0 } loc x k with
1,608✔
49
  | Expected (loc, expected) ->
29,110✔
50
    (match on_error with
51
     | None -> Location.raise_errorf ~loc "%s expected" expected
×
52
     | Some f -> f expected)
29,110✔
53
;;
54

55
module Packed = struct
56
  type ('a, 'b) t = T : ('a, 'b, 'c) Ast_pattern0.t * 'b -> ('a, 'c) t
57

58
  let create t f = T (t, f)
×
59
  let parse (T (t, f)) loc x = parse t loc x f
×
60
end
61

62
let __ : 'a 'b. ('a, 'a -> 'b, 'b) t =
63
  T
64
    (fun ctx _loc x k ->
65
      incr_matched ctx;
2,800✔
66
      k x)
2,800✔
67
;;
68

69
let as__ : 'a 'b 'c. ('a, 'b, 'c) t -> ('a, 'a -> 'b, 'c) t =
70
  fun (T f1) ->
71
  T
3,610✔
72
    (fun ctx loc x k ->
73
      let k = f1 ctx loc x (k x) in
260✔
74
      k)
120✔
75
;;
76

77
let pair (T f1) (T f2) =
78
  T
9,400✔
79
    (fun ctx loc (x1, x2) k ->
80
      let k = f1 ctx loc x1 k in
410✔
81
      let k = f2 ctx loc x2 k in
391✔
82
      k)
262✔
83
;;
84

85
let ( ** ) = pair
86

87
let __' =
88
  T
89
    (fun ctx loc x k ->
90
      incr_matched ctx;
21✔
91
      k { loc; txt = x })
21✔
92
;;
93

94
let drop : 'a 'b. ('a, 'b, 'b) t =
95
  T
96
    (fun ctx _loc _ k ->
97
      incr_matched ctx;
1,204✔
98
      k)
1,204✔
99
;;
100

101
let cst ~to_string ?(equal = Stdlib.( = )) v =
5,407✔
102
  T
5,407✔
103
    (fun ctx loc x k ->
104
      if equal x v
135✔
105
      then (
51✔
106
        incr_matched ctx;
107
        (* printf "cst succeeded for %s\n%!" (to_string v); *)
108
        k)
51✔
109
      else fail loc (to_string v))
84✔
110
;;
111

112
let int v = cst ~to_string:Int.to_string v
470✔
113
let char v = cst ~to_string:(Printf.sprintf "%C") v
×
114
let string v = cst ~to_string:(Printf.sprintf "%S") v
4,937✔
115
let float v = cst ~to_string:Float.to_string v
×
116
let int32 v = cst ~to_string:Int32.to_string v
×
117
let int64 v = cst ~to_string:Int64.to_string v
×
118
let nativeint v = cst ~to_string:Nativeint.to_string v
×
119
let bool v = cst ~to_string:Bool.to_string v
×
120

121
let false_ =
122
  T
123
    (fun ctx loc x k ->
124
      match x with
×
125
      | false ->
×
126
        ctx.matched <- ctx.matched + 1;
127
        k
128
      | _ -> fail loc "false")
×
129
;;
130

131
let true_ =
132
  T
133
    (fun ctx loc x k ->
134
      match x with
×
135
      | true ->
×
136
        ctx.matched <- ctx.matched + 1;
137
        k
138
      | _ -> fail loc "true")
×
139
;;
140

141
let nil =
142
  T
143
    (fun ctx loc x k ->
144
      log "trying [] \n%!";
405✔
145
      match x with
405✔
146
      | [] ->
317✔
147
        ctx.matched <- ctx.matched + 1;
148
        k
149
      | _ -> fail loc "[]")
88✔
150
;;
151

152
let ( ^:: ) (T f0) (T f1) =
153
  T
22,529✔
154
    (fun ctx loc x k ->
155
      match x with
654✔
156
      | x0 :: x1 ->
603✔
157
        ctx.matched <- ctx.matched + 1;
158
        (* Format.printf "trying elem of cons cell\n%!"; *)
159
        let k = f0 ctx loc x0 k in
160
        (* Format.printf "trying tail of cons cell\n%!"; *)
161
        let k = f1 ctx loc x1 k in
501✔
162
        (* Format.printf "trying  cons cell succeeded\n%!"; *)
163
        k
361✔
164
      | _ ->
51✔
165
        (* Format.printf "failing elem of cons cell\n%!"; *)
166
        fail loc "::")
167
;;
168

169
let list (T fel) =
170
  let rec helper acc ctx loc xs k =
2✔
171
    match xs with
6✔
172
    | [] -> k (List.rev acc)
2✔
173
    | h :: tl ->
4✔
174
      (match fel ctx loc h Fun.id with
175
       | x -> helper (x :: acc) ctx loc tl k)
4✔
176
  in
177
  T (fun ctx loc xs k -> helper [] ctx loc xs k)
2✔
178
;;
179

180
let none =
181
  T
182
    (fun ctx loc x k ->
183
      match x with
72✔
184
      | None ->
72✔
185
        ctx.matched <- ctx.matched + 1;
186
        k
187
      | _ -> fail loc "None")
×
188
;;
189

190
let some (T f0) =
191
  T
8,210✔
192
    (fun ctx loc x k ->
193
      match x with
156✔
194
      | Some x0 ->
156✔
195
        ctx.matched <- ctx.matched + 1;
196
        let k = f0 ctx loc x0 k in
197
        k
73✔
198
      | _ -> fail loc "Some")
×
199
;;
200

201
let triple (T f1) (T f2) (T f3) =
202
  T
×
203
    (fun ctx loc (x1, x2, x3) k ->
204
      let k = f1 ctx loc x1 k in
×
205
      let k = f2 ctx loc x2 k in
×
206
      let k = f3 ctx loc x3 k in
×
207
      k)
×
208
;;
209

210
let alt (T f1) (T f2) =
211
  T
12,387✔
212
    (fun ctx loc x k ->
213
      let backup = save_context ctx in
41,891✔
214
      try f1 ctx loc x k with
822✔
215
      | e1 ->
41,069✔
216
        let m1 = save_context ctx in
217
        restore_context ctx backup;
41,069✔
218
        (try f2 ctx loc x k with
753✔
219
         | e2 ->
40,316✔
220
           let m2 = save_context ctx in
221
           if m1 >= m2
40,316✔
222
           then (
39,989✔
223
             restore_context ctx m1;
224
             raise e1)
39,989✔
225
           else raise e2))
327✔
226
;;
227

228
let ( ||| ) = alt
229
let map (T func) ~f = T (fun ctx loc x k -> func ctx loc x (f k))
×
230
let map' (T func) ~f = T (fun ctx loc x k -> func ctx loc x (f loc k))
×
231
let map_result (T func) ~f = T (fun ctx loc x k -> f (func ctx loc x k))
×
232
let ( >>| ) t f = map t ~f
×
233
let map0 (T func) ~f = T (fun ctx loc x k -> func ctx loc x (k f))
336✔
234
let map1 (T func) ~f = T (fun ctx loc x k -> func ctx loc x (fun a -> k (f a)))
606✔
235
let map2 (T func) ~f = T (fun ctx loc x k -> func ctx loc x (fun a b -> k (f a b)))
370✔
236
let map3 (T func) ~f = T (fun ctx loc x k -> func ctx loc x (fun a b c -> k (f a b c)))
57✔
237

238
let map4 (T func) ~f =
239
  T (fun ctx loc x k -> func ctx loc x (fun a b c d -> k (f a b c d)))
9✔
240
;;
241

242
let map5 (T func) ~f =
243
  T (fun ctx loc x k -> func ctx loc x (fun a b c d e -> k (f a b c d e)))
22✔
244
;;
245

246
let map6 (T func) ~f:fmap =
247
  T (fun ctx loc x k -> func ctx loc x (fun a b c d e f -> k (fmap a b c d e f)))
1✔
248
;;
249

250
let map7 (T func) ~f:fmap =
251
  T (fun ctx loc x k -> func ctx loc x (fun a b c d e f g -> k (fmap a b c d e f g)))
3✔
252
;;
253

254
let map0' (T func) ~f = T (fun ctx loc x k -> func ctx loc x (k (f loc)))
×
255
let map1' (T func) ~f = T (fun ctx loc x k -> func ctx loc x (fun a -> k (f loc a)))
×
256
let map2' (T func) ~f = T (fun ctx loc x k -> func ctx loc x (fun a b -> k (f loc a b)))
×
257
let map_result (T func) ~f = T (fun ctx loc x k -> f (func ctx loc x k))
×
258
let alt_option some none = alt (map1 some ~f:(fun x -> Some x)) (map0 none ~f:None)
×
259

260
let many (T f) =
261
  T (fun ctx loc l k -> k (ListLabels.map l ~f:(fun x -> f ctx loc x (fun x -> x))))
×
262
;;
263

264
let loc (T f) = T (fun ctx _loc (x : _ Ppxlib.Loc.t) k -> f ctx x.loc x.txt k)
×
265
let pack0 t = map t ~f:(fun f -> f ())
×
266
let pack2 t = map t ~f:(fun f x y -> f (x, y))
×
267
let pack3 t = map t ~f:(fun f x y z -> f (x, y, z))
×
268

269
(* end of copy-paste from https://github.com/ocaml-ppx/ppxlib/blob/0.22.2/src/ast_pattern.ml *)
270
(* TODO: deal with licencing issues *)
271

272
let lident (T fident) =
273
  T
585✔
274
    (fun ctx loc x k ->
275
      match x with
136✔
276
      | Longident.Lident id ->
126✔
277
        ctx.matched <- ctx.matched + 1;
278
        k |> fident ctx loc id
279
      | _ -> fail loc "lident")
10✔
280
;;
281

282
let elongident (lident : Longident.t) =
283
  T
57✔
284
    (fun ctx loc x k ->
285
      if Stdlib.compare x lident = 0
183✔
286
      then (
15✔
287
        ctx.matched <- ctx.matched + 1;
288
        k)
289
      else fail loc "elongident")
168✔
290
;;
291

292
let path_pident (T fident) =
293
  T
2✔
294
    (fun ctx loc x k ->
295
      match x with
2✔
296
      | Path.Pident id ->
1✔
297
        ctx.matched <- ctx.matched + 1;
298
        k |> fident ctx loc id
299
      | _ -> fail loc "path_pident")
1✔
300
;;
301

302
let path xs =
303
  let rec helper ps ctx loc x k =
5,691✔
304
    let cmp_names l r =
13,444✔
305
      let ans = String.equal l r in
7,060✔
306
      (* printf "\t\tCompare names %s and %s:  %b\n%!" l r ans; *)
307
      ans
7,060✔
308
    in
309
    match x, ps with
310
    | Path.Pident id, [ id0 ] ->
117✔
311
      if cmp_names (Ident.name id) id0
117✔
312
      then (
110✔
313
        let () = ctx.matched <- ctx.matched + 1 in
314
        k)
315
      else fail loc "path"
7✔
316
    | Path.Pdot (next, id), id0 :: ids when cmp_names id id0 -> helper ids ctx loc next k
152✔
317
    | Path.Papply _, _ -> fail loc "path got Papply"
×
318
    | _ -> fail loc (sprintf "path %s" (String.concat "." xs))
13,175✔
319
  in
320
  T (helper (List.rev xs))
5,691✔
321
;;
322

323
let path_of_list = function
324
  | [] -> failwith "Bad argument: path_of_list"
1✔
325
  | s :: tl ->
2✔
326
    ListLabels.fold_left
327
      tl
328
      ~init:(Path.Pident (Ident.create_local s))
2✔
329
      ~f:(fun acc x -> Path.Pdot (acc, x))
4✔
330
;;
331

332
let%test_module " " =
333
  (module struct
334
    [@@@coverage off]
335

336
    let names = [ "Stdlib!"; "List"; "length" ]
337

338
    [%%if ocaml_version < (5, 0, 0)]
339

340
    let pp_path = Path.print
341

342
    [%%else]
343

344
    let pp_path = Format_doc.compat Path.print
345

346
    [%%endif]
347

348
    let%test_unit _ =
349
      let old = !Clflags.unique_ids in
350
      Clflags.unique_ids := false;
351
      [%test_eq: Base.string]
352
        "Stdlib!.List.length"
353
        (asprintf "%a" pp_path (path_of_list names));
354
      Clflags.unique_ids := old
355
    ;;
356

357
    let%test _ =
358
      let noloc =
359
        Warnings.
360
          { loc_start = Lexing.dummy_pos; loc_end = Lexing.dummy_pos; loc_ghost = true }
361
      in
362
      parse (path names) noloc ~on_error:(fun _ -> false) (path_of_list names) true
363
    ;;
364
  end)
365
;;
366

367
open Typedtree
368

369
let econst (T f0) =
370
  T
2✔
371
    (fun ctx loc x k ->
372
      match x.exp_desc with
2✔
373
      | Texp_constant n ->
2✔
374
        ctx.matched <- ctx.matched + 1;
375
        f0 ctx loc n k
376
      | _ -> fail loc (sprintf "econst"))
×
377
;;
378

379
let eint (T f0) =
380
  T
470✔
381
    (fun ctx loc x k ->
382
      match x.exp_desc with
17✔
383
      | Texp_constant (Asttypes.Const_int n) ->
8✔
384
        ctx.matched <- ctx.matched + 1;
385
        f0 ctx loc n k
386
      | _ -> fail loc "eint")
9✔
387
;;
388

389
let estring =
390
  T
391
    (fun ctx loc x k ->
392
      match x.exp_desc with
15✔
393
      | Texp_constant (Asttypes.Const_string (s, _, None)) ->
15✔
394
        ctx.matched <- ctx.matched + 1;
395
        k s
396
      | _ -> fail loc "estring")
×
397
;;
398

399
let ebool =
400
  T
401
    (fun ctx loc x k ->
402
      match x.exp_desc with
95✔
403
      | Texp_construct ({ txt = Lident "true" }, _, []) ->
11✔
404
        ctx.matched <- ctx.matched + 1;
405
        k true
406
      | Texp_construct ({ txt = Lident "false" }, _, []) ->
8✔
407
        ctx.matched <- ctx.matched + 1;
408
        k false
409
      | _ -> fail loc (sprintf "ebool"))
76✔
410
;;
411

412
[%%if ocaml_version < (5, 0, 0)]
413

414
let tpat_var (T fname) =
415
  T
1,521✔
416
    (fun ctx loc x k ->
417
      match x.pat_desc with
51✔
418
      | Tpat_var (_, { txt }) ->
51✔
419
        ctx.matched <- ctx.matched + 1;
420
        k |> fname ctx loc txt
421
      | _ -> fail loc "tpat_var")
×
422
;;
423

424
let tpat_id (T fname) =
425
  T
1,893✔
426
    (fun ctx loc x k ->
427
      match x.pat_desc with
293✔
428
      | Tpat_var (id, { loc }) ->
232✔
429
        ctx.matched <- ctx.matched + 1;
430
        k |> fname ctx loc id
431
      | _ -> fail loc "tpat_var_id")
61✔
432
;;
433

434
[%%else]
435

436
let tpat_var (T fname) =
437
  T
438
    (fun (type kind) ctx loc (x : kind pattern_desc pattern_data) k ->
439
      match x.pat_desc with
440
      | Tpat_var (_, { txt }, _uid) ->
441
        ctx.matched <- ctx.matched + 1;
442
        k |> fname ctx loc txt
443
      | Tpat_value v ->
444
        (match (v :> pattern).pat_desc with
445
         | Tpat_var (_, { txt }, _uid) ->
446
           ctx.matched <- ctx.matched + 1;
447
           k |> fname ctx loc txt
448
         | _ -> fail loc "tpat_var")
449
      | _ -> fail loc "tpat_var")
450
;;
451

452
let tpat_id (T fname) =
453
  T
454
    (fun (type kind) ctx loc (x : kind pattern_desc pattern_data) k ->
455
      match x.pat_desc with
456
      | Typedtree.Tpat_value v ->
457
        (match (v :> pattern).pat_desc with
458
         | Tpat_var (id, { loc }, _uid) ->
459
           ctx.matched <- ctx.matched + 1;
460
           k |> fname ctx loc id
461
         | _ -> fail loc "tpat_id")
462
      | Tpat_var (id, { loc }, _uid) ->
463
        ctx.matched <- ctx.matched + 1;
464
        k |> fname ctx loc id
465
      | _ -> fail loc "tpat_id 2")
466
;;
467

468
[%%endif]
469

470
let tpat_constructor (T fname) (T fargs) =
471
  T
5,804✔
472
    (fun ctx loc x k ->
473
      match x.pat_desc with
84✔
474
      | Tpat_construct ({ txt }, _, args, _) ->
75✔
475
        ctx.matched <- ctx.matched + 1;
476
        k |> fname ctx loc txt |> fargs ctx loc args
66✔
477
      | _ -> fail loc "tpat_constructor")
9✔
478
;;
479

480
let tpat_tuple (T fargs) =
481
  T
×
482
    (fun ctx loc x k ->
483
      match x.pat_desc with
×
484
      | Tpat_tuple pats ->
×
485
        ctx.matched <- ctx.matched + 1;
486
        k |> fargs ctx loc pats
487
      | _ -> fail loc "tpat_tuple")
×
488
;;
489

490
let tpat_value (T fpat) =
491
  T
×
492
    (fun ctx loc x k ->
493
      match x.pat_desc with
×
494
      | Tpat_value arg ->
×
495
        let inner = (arg :> value pattern_desc pattern_data) in
496
        ctx.matched <- ctx.matched + 1;
497
        k |> fpat ctx loc inner
498
      | _ -> fail loc "tpat_value")
×
499
;;
500

501
let tpat_exception (T fpat) =
502
  T
×
503
    (fun ctx loc x k ->
504
      match x.pat_desc with
×
505
      | Tpat_exception exc ->
×
506
        ctx.matched <- ctx.matched + 1;
507
        k |> fpat ctx loc exc
508
      | _ -> fail loc "tpat_exception")
×
509
;;
510

511
let tpat_any =
512
  T
513
    (fun ctx loc x k ->
514
      match x.pat_desc with
3✔
515
      | Tpat_any ->
2✔
516
        ctx.matched <- ctx.matched + 1;
517
        k
518
      | _ -> fail loc "tpat_any")
1✔
519
;;
520

521
let texp_ident (T fpath) =
522
  T
14,736✔
523
    (fun ctx loc x k ->
524
      let __ _ = log "texp_ident %a\n%!" My_printtyped.expr x in
×
525
      match x.exp_desc with
526
      | Texp_ident (path, _, _) ->
11,727✔
527
        ctx.matched <- ctx.matched + 1;
528
        let ans = fpath ctx loc path k in
529
        log "texp_ident + %a\n%!" My_printtyped.expr x;
798✔
530
        ans
798✔
531
      | _ -> fail loc "texp_ident")
3,131✔
532
;;
533

534
let texp_ident_loc (T fpath) =
535
  T
1,249✔
536
    (fun ctx loc x k ->
537
      match x.exp_desc with
15✔
538
      | Texp_ident (path, _, _) ->
10✔
539
        ctx.matched <- ctx.matched + 1;
540
        k x.exp_loc |> fpath ctx loc path
10✔
541
      | _ -> fail loc "texp_ident")
5✔
542
;;
543

544
(* TODO(Kakadu): accept and Ident, and not a string *)
545
let pident (T fstr) =
546
  T
7,449✔
547
    (fun ctx loc x k ->
548
      match x with
211✔
549
      | Path.Pident id -> fstr ctx loc (Ident.name id) k
93✔
550
      | _ -> fail loc "pident")
118✔
551
;;
552

553
let texp_ident_typ (T fpath) (T ftyp) =
554
  T
284✔
555
    (fun ctx loc x k ->
556
      (* let __ _ = Format.printf "texp_ident_typ %a\n%!" MyPrinttyped.expr x in *)
557
      match x.exp_desc with
1,599✔
558
      | Texp_ident (path, _, typ) ->
829✔
559
        ctx.matched <- ctx.matched + 1;
560
        k |> fpath ctx loc path |> ftyp ctx loc typ.Types.val_type
437✔
561
      | _ -> fail loc "texp_ident_typ")
770✔
562
;;
563

564
[%%if ocaml_version < (5, 0, 0)]
565

566
let texp_assert (T fexp) =
567
  T
57✔
568
    (fun ctx loc x k ->
569
      match x.exp_desc with
1,459✔
570
      | Texp_assert e ->
1✔
571
        ctx.matched <- ctx.matched + 1;
572
        fexp ctx loc e k
573
      | _ -> fail loc "texp_assert")
1,458✔
574
;;
575

576
[%%else]
577

578
let texp_assert (T fexp) =
579
  T
580
    (fun ctx loc x k ->
581
       match x.exp_desc with
582
       | Texp_assert (e, _) ->
583
         ctx.matched <- ctx.matched + 1;
584
         fexp ctx loc e k
585
       | _ -> fail loc "texp_assert"
586
     : context -> Warnings.loc -> expression -> 'a -> 'b)
587
;;
588

589
[%%endif]
590

591
let texp_apply (T f0) (T args0) =
592
  T
5,980✔
593
    (fun ctx loc x k ->
594
      (* let __ _ = log "texp_apply %a\n%!" MyPrinttyped.expr x in *)
595
      match x.exp_desc with
25,719✔
596
      | Texp_apply (f, args) ->
3,584✔
597
        ctx.matched <- ctx.matched + 1;
598
        let ans = k |> f0 ctx loc f |> args0 ctx loc args in
73✔
599
        (* let _ = log "texp_apply + %a\n%!" MyPrinttyped.expr x in *)
600
        ans
43✔
601
      | _ -> fail loc "texp_apply")
22,135✔
602
;;
603

604
let texp_apply_nolabelled (T f0) (T args0) =
605
  let exception EarlyExit in
1,542✔
606
  T
607
    (fun ctx loc x k ->
608
      match x.exp_desc with
3,088✔
609
      | Texp_apply (f, args) ->
482✔
610
        ctx.matched <- ctx.matched + 1;
611
        let k = f0 ctx loc f k in
612
        (try
95✔
613
           let args =
614
             ListLabels.map args ~f:(function
615
               | Asttypes.Labelled _, _ | Asttypes.Optional _, _ | _, None ->
×
616
                 raise EarlyExit
617
               | _, Some x -> x)
206✔
618
           in
619
           args0 ctx loc args k
22✔
620
         with
621
         | EarlyExit -> fail loc "texp_apply: None among the arguments ")
2✔
622
      | _ -> fail loc "texp_apply")
2,606✔
623
;;
624

625
let texp_construct (T fpath) (T fcd) (T fargs) =
626
  T
218✔
627
    (fun ctx loc x k ->
628
      match x.exp_desc with
1,483✔
629
      | Texp_construct (path, cd, args) ->
192✔
630
        ctx.matched <- ctx.matched + 1;
631
        let k = fpath ctx loc path.txt k in
632
        k |> fcd ctx loc cd |> fargs ctx loc args
24✔
633
      | _ -> fail loc (sprintf "texp_construct"))
1,291✔
634
;;
635

636
let texp_assert_false () = texp_assert (texp_construct (lident (string "false")) drop nil)
57✔
637

638
let texp_let (T fvbs) (T fexpr) =
639
  T
1,472✔
640
    (fun ctx loc x k ->
641
      match x.exp_desc with
1,268✔
642
      | Texp_let (_flg, vbs, expr) ->
18✔
643
        ctx.matched <- ctx.matched + 1;
644
        k |> fvbs ctx loc vbs |> fexpr ctx loc expr
15✔
645
      | _ -> fail loc (sprintf "texp_let"))
1,250✔
646
;;
647

648
let nolabel =
649
  T
650
    (fun ctx loc x k ->
651
      match x with
255✔
652
      | Asttypes.Nolabel ->
236✔
653
        ctx.matched <- ctx.matched + 1;
654
        k
655
      | _ -> fail loc "nolabel")
19✔
656
;;
657

658
let labelled (T fstr) =
659
  T
58✔
660
    (fun ctx loc x k ->
661
      match x with
3✔
662
      | Asttypes.Labelled s ->
2✔
663
        ctx.matched <- ctx.matched + 1;
664
        k |> fstr ctx loc s
665
      | _ -> fail loc "labelled")
1✔
666
;;
667

668
let texp_apply1 f x = texp_apply f ((nolabel ** some x) ^:: nil)
3,408✔
669
let texp_apply2 f x y = texp_apply f ((nolabel ** some x) ^:: (nolabel ** some y) ^:: nil)
2,173✔
670

671
[%%if ocaml_version < (4, 11, 2)]
672

673
(* 4.10 *)
674
type case_val = Typedtree.case
675
type case_comp = Typedtree.case
676
type value_pat = pattern
677
type comp_pat = pattern
678

679
[%%else]
680

681
type case_val = value case
682
type case_comp = computation case
683
type value_pat = value pattern_desc pattern_data
684
type comp_pat = computation pattern_desc pattern_data
685

686
[%%endif]
687
[%%if ocaml_version < (5, 0, 0)]
688

689
let texp_function (T fcases) =
690
  T
×
691
    (fun ctx loc e k ->
692
      match e.exp_desc with
×
693
      | Texp_function { cases } ->
×
694
        ctx.matched <- ctx.matched + 1;
695
        k |> fcases ctx loc cases
696
      | _ -> fail loc "texp_function")
×
697
;;
698

699
let texp_function_body (T fargs) (T frhs) =
700
  let rec helper acc ctx loc e k =
6,802✔
701
    match e.exp_desc with
6,290✔
702
    | Texp_function
955✔
703
        { cases =
704
            [ { c_lhs = { pat_desc = Tpat_var (pid, _); pat_loc; _ }
705
              ; c_rhs
706
              ; c_guard = None
707
              }
708
            ]
709
        ; arg_label
710
        ; partial = Total
711
        } -> helper ((arg_label, (pid, pat_loc)) :: acc) ctx loc c_rhs k
712
    | _ when [] = acc -> fail loc "texp_function_body"
4,638✔
713
    | _ -> k |> fargs ctx loc (List.rev acc) |> frhs ctx loc e
609✔
714
  in
715
  T (helper [])
6,802✔
716
;;
717

718
let texp_function_cases
719
  :  ((Asttypes.arg_label * (Ident.t * Location.t)) list, 'a, 'b) t
720
  -> (value case list, 'b, 'c) t
721
  -> (expression, 'a, 'c) t
722
  =
723
  fun (T fargs) (T frhs) ->
724
  let rec helper acc ctx loc e k =
5,827✔
725
    match e.exp_desc with
4,741✔
726
    | Typedtree.Texp_function
566✔
727
        { cases =
728
            [ { c_lhs = { pat_desc = Tpat_var (pid, tag); _ }; c_rhs; c_guard = _ } ]
729
        ; arg_label
730
        ; partial = Total
731
        } -> helper ((arg_label, (pid, tag.loc)) :: acc) ctx loc c_rhs k
732
    | Texp_function { cases = _ :: _ :: _ as cases; _ } ->
91✔
733
      k |> fargs ctx loc (List.rev acc) |> frhs ctx loc cases
62✔
734
    | _ -> fail loc "texp_function_cases"
4,084✔
735
  in
736
  T (helper [])
5,827✔
737
;;
738

739
[%%else]
740

741
let texp_function_cases (T fparam) (T fcases) =
742
  T
743
    (fun ctx loc e k ->
744
      match e.exp_desc with
745
      | Texp_function (params, Tfunction_cases cases) ->
746
        ctx.matched <- ctx.matched + 1;
747
        k
748
        |> fparam
749
             ctx
750
             loc
751
             (List.map (fun p -> p.Typedtree.fp_arg_label, (p.fp_param, p.fp_loc)) params)
752
        |> fcases ctx loc cases.cases
753
      | _ -> fail loc "texp_function")
754
;;
755

756
let texp_function_body (T fparam) (T fcases) =
757
  T
758
    (fun ctx loc e k ->
759
      match e.exp_desc with
760
      | Typedtree.Texp_function (params, Tfunction_body e) ->
761
        ctx.matched <- ctx.matched + 1;
762
        k
763
        |> fparam
764
             ctx
765
             loc
766
             (List.map (fun p -> p.fp_arg_label, (p.fp_param, p.fp_loc)) params)
767
        |> fcases ctx loc e
768
      | _ -> fail loc "texp_function")
769
;;
770

771
[%%endif]
772

773
let case (T pat) (T guard) (T rhs) =
774
  T
7,330✔
775
    (fun ctx loc { c_lhs; c_rhs; c_guard } k ->
776
      k |> pat ctx loc c_lhs |> guard ctx loc c_guard |> rhs ctx loc c_rhs)
53✔
777
;;
778

779
let ccase (T pat) (T guard) (T rhs) =
780
  T
×
781
    (fun ctx loc { c_lhs; c_rhs; c_guard } k ->
782
      k |> pat ctx loc c_lhs |> guard ctx loc c_guard |> rhs ctx loc c_rhs)
×
783
;;
784

785
[%%if ocaml_version < (5, 0, 0)]
786

787
let texp_match (T fexpr) (T fcomp_cases) (T fval_cases) =
788
  let rec split (type _a) (comps, vals) (cases : _ case list) =
2,731✔
789
    let _ : case_comp list = comps in
215✔
790
    let _ : case_val list = vals in
791
    let wrap (type a) comps vals : a case -> case_comp list * case_val list =
792
      let _ : case_comp list = comps in
147✔
793
      let _ : case_val list = vals in
794
      fun case ->
795
        match case with
147✔
796
        | { c_lhs = { pat_desc = Tpat_value p }; _ } ->
142✔
797
          ( comps
798
          , { c_lhs = (p :> pattern); c_rhs = case.c_rhs; c_guard = case.c_guard } :: vals
799
          )
800
        | { c_lhs = { pat_desc = Tpat_any }; _ } -> comps, (case :> case_val) :: vals
×
801
        | { c_lhs = { pat_desc = Tpat_var _ }; _ } -> comps, (case :> case_val) :: vals
×
802
        | { c_lhs = { pat_desc = Tpat_alias _ }; _ } -> comps, (case :> case_val) :: vals
×
803
        | { c_lhs = { pat_desc = Tpat_constant _ }; _ } ->
×
804
          comps, (case :> case_val) :: vals
805
        | { c_lhs = { pat_desc = Tpat_construct _ }; _ } ->
×
806
          comps, (case :> case_val) :: vals
807
        | { c_lhs = { pat_desc = Tpat_variant _ }; _ } ->
×
808
          comps, (case :> case_val) :: vals
809
        | { c_lhs = { pat_desc = Tpat_record _ }; _ } -> comps, (case :> case_val) :: vals
×
810
        | { c_lhs = { pat_desc = Tpat_array _ }; _ } -> comps, (case :> case_val) :: vals
×
811
        | { c_lhs = { pat_desc = Tpat_lazy _ }; _ } -> comps, (case :> case_val) :: vals
×
812
        (* | { c_lhs = { pat_desc = Tpat_value _ }; _ } -> (case :> case_comp) :: comps, vals *)
813
        | { c_lhs = { pat_desc = Tpat_exception _ }; _ } ->
3✔
814
          (case :> case_comp) :: comps, vals
815
        | { c_lhs = { pat_desc = Tpat_or _ }; _ } ->
2✔
816
          (* TODO(Kakadu): What to do here? We need to look deeply into or-pattern to understand where to place it?
817
            See issue #76
818
          *)
819
          (* failwith "Or-patterns are not yet implemented" *)
820
          comps, vals
821
        | { c_lhs; _ } ->
×
822
          (* Format.eprintf "%a\n%!" My_printtyped.pattern c_lhs; *)
823
          Format.eprintf
824
            "Unsupported pattern: tag = %d, is_block = %b\n"
825
            Obj.(tag @@ repr c_lhs)
×
826
            Obj.(is_block @@ repr c_lhs);
×
827
          assert false
×
828
    in
829
    match cases with
830
    | h :: tl -> split (wrap comps vals h) tl
147✔
831
    | [] -> List.rev comps, List.rev vals
68✔
832
  in
833
  T
834
    (fun ctx loc e k ->
835
      match e.exp_desc with
2,950✔
836
      | Texp_match (e, cases, _) ->
68✔
837
        ctx.matched <- ctx.matched + 1;
838
        let comp_cases, val_cases = split ([], []) cases in
839
        (* log
840
           "There are %d comp cases and %d val cases"
841
           (List.length comp_cases)
842
           (List.length val_cases); *)
843
        k
68✔
844
        |> fexpr ctx loc e
845
        |> fcomp_cases ctx loc comp_cases
62✔
846
        |> fval_cases ctx loc val_cases
62✔
847
      | _ -> fail loc "texp_match")
2,882✔
848
;;
849

850
[%%else]
851

852
let texp_match (T fexpr) (T fcomp_cases) (T fval_cases) =
853
  T
854
    (fun ctx loc e k ->
855
      match e.Typedtree.exp_desc with
856
      | Texp_match (e, ccases, vcases, _) ->
857
        let ccases, vcases =
858
          List.fold_left
859
            (fun (cacc, vacc) c ->
860
              match c.c_lhs.pat_desc with
861
              | Tpat_value v ->
862
                cacc, { c with c_lhs = (v :> value general_pattern) } :: vacc
863
              | _ -> cacc, vacc)
864
            ([], vcases)
865
            ccases
866
        in
867
        ctx.matched <- ctx.matched + 1;
868
        k |> fexpr ctx loc e |> fcomp_cases ctx loc ccases |> fval_cases ctx loc vcases
869
      | _ -> fail loc "texp_match")
870
;;
871

872
[%%endif]
873

874
let texp_ite (T pred) (T fthen) (T felse) =
875
  T
684✔
876
    (fun ctx loc e k ->
877
      match e.exp_desc with
7,907✔
878
      | Texp_ifthenelse (p, thenb, elseb) ->
185✔
879
        ctx.matched <- ctx.matched + 1;
880
        k |> pred ctx loc p |> fthen ctx loc thenb |> felse ctx loc elseb
77✔
881
      | _ -> fail loc "texp_ite")
7,722✔
882
;;
883

884
[%%if ocaml_version < (5, 0, 0)]
885

886
let texp_try (T fexpr) (T fcases) =
887
  T
57✔
888
    (fun ctx loc e k ->
889
      match e.exp_desc with
1,461✔
890
      | Texp_try (e, cases) ->
3✔
891
        ctx.matched <- ctx.matched + 1;
892
        k |> fexpr ctx loc e |> fcases ctx loc cases
3✔
893
      | _ -> fail loc "texp_try")
1,458✔
894
;;
895

896
[%%else]
897

898
let texp_try (T fexpr) (T fcases) =
899
  T
900
    (fun ctx loc e k ->
901
      match e.exp_desc with
902
      | Typedtree.Texp_try (e, cases, _) ->
903
        (* TODO: support effects *)
904
        ctx.matched <- ctx.matched + 1;
905
        k |> fexpr ctx loc e |> fcases ctx loc cases
906
      | _ -> fail loc "texp_try")
907
;;
908

909
[%%endif]
910

911
let texp_record (T fext) (T ffields) =
912
  T
1,469✔
913
    (fun ctx loc e k ->
914
      match e.exp_desc with
1,469✔
915
      | Texp_record { fields; extended_expression; _ } ->
19✔
916
        ctx.matched <- ctx.matched + 1;
917
        k |> fext ctx loc extended_expression |> ffields ctx loc fields
19✔
918
      | _ -> fail loc "texp_record")
1,450✔
919
;;
920

921
let texp_field (T fexpr) (T fdesc) =
922
  T
56✔
923
    (fun ctx loc e k ->
924
      match e.exp_desc with
51✔
925
      | Texp_field (e, _, desc) ->
17✔
926
        ctx.matched <- ctx.matched + 1;
927
        k |> fexpr ctx loc e |> fdesc ctx loc desc
17✔
928
      | _ -> fail loc "texp_field")
34✔
929
;;
930

931
let label_desc (T fname) =
932
  T
112✔
933
    (fun ctx loc e k ->
934
      match e with
95✔
935
      | { Types.lbl_name; _ } ->
95✔
936
        ctx.matched <- ctx.matched + 1;
937
        k |> fname ctx loc lbl_name)
938
;;
939

940
let rld_kept =
941
  T
942
    (fun ctx loc e k ->
943
      match e with
56✔
944
      | Kept _ ->
×
945
        ctx.matched <- ctx.matched + 1;
946
        k
947
      | _ -> fail loc "rld_kept")
56✔
948
;;
949

950
let rld_overriden (T flident) (T fexpr) =
951
  T
112✔
952
    (fun ctx loc e k ->
953
      match e with
95✔
954
      | Overridden ({ txt = lident }, e) ->
95✔
955
        ctx.matched <- ctx.matched + 1;
956
        k |> flident ctx loc lident |> fexpr ctx loc e
85✔
957
      | _ -> fail loc "rld_overriden")
×
958
;;
959

960
let value_binding (T fpat) (T fexpr) =
961
  T
1,576✔
962
    (fun ctx loc { vb_pat; vb_expr } k ->
963
      ctx.matched <- ctx.matched + 1;
119✔
964
      k |> fpat ctx loc vb_pat |> fexpr ctx loc vb_expr)
117✔
965
;;
966

967
(*   let hack0 (T path0) =
968
     T
969
     (fun ctx loc x k ->
970
     match x.Types.val_type.Types.desc with
971
     | Tconstr (path, [], _) ->
972
     ctx.matched <- ctx.matched + 1;
973
     path0 ctx loc path k
974
     | _ -> fail loc "hack0")
975
     ;;
976

977
     let hack1 ?(on_vd = drop) (T path0) =
978
     T
979
     (fun ctx loc x k ->
980
     match x.exp_desc with
981
     | Texp_ident (path, _, vd) ->
982
     ctx.matched <- ctx.matched + 1;
983
     let (T fvd) = on_vd in
984
     k |> path0 ctx loc path |> fvd ctx loc vd
985
     | _ -> fail loc "texp_ident")
986
     ;;
987

988
     let __ path = hack1 __ path *)
989
let rec core_typ (T ftexpr) = T (fun ctx loc x k -> ftexpr ctx loc x.ctyp_type k)
169✔
990

991
let rec typ_constr (T fpath) (T fargs) =
992
  let rec helper ctx loc x k =
673✔
993
    (* Format.printf "typ = %a\n%!" Printtyp.type_expr x; *)
994
    match Types.get_desc x with
2,374✔
995
    | Tconstr (path, args, _) ->
1,277✔
996
      ctx.matched <- ctx.matched + 1;
997
      k |> fpath ctx loc path |> fargs ctx loc args
205✔
998
    | Tlink arg -> helper ctx loc arg k
×
999
    | _ -> fail loc "typ_constr"
1,097✔
1000
  in
1001
  T helper
1002
;;
1003

1004
let rec typ_arrow (T l) (T r) =
1005
  let rec helper ctx loc x k =
344✔
1006
    (* Format.printf "typ = %a\n%!" Printtyp.type_expr x; *)
1007
    match Types.get_desc x with
22✔
1008
    | Tarrow (_, tl, tr, _) ->
22✔
1009
      ctx.matched <- ctx.matched + 1;
1010
      k |> l ctx loc tl |> r ctx loc tr
22✔
1011
    | _ -> fail loc "typ_arrow"
×
1012
  in
1013
  T helper
1014
;;
1015

1016
let typ_kind_abstract =
1017
  T
1018
    (fun ctx loc x k ->
1019
      match x with
67✔
1020
      | Typedtree.Ttype_abstract ->
8✔
1021
        ctx.matched <- ctx.matched + 1;
1022
        k
1023
      | _ -> fail loc "typ_kind_abstract")
59✔
1024
;;
1025

1026
let typ_kind_open =
1027
  T
1028
    (fun ctx loc x k ->
1029
      match x with
67✔
1030
      | Typedtree.Ttype_open ->
×
1031
        ctx.matched <- ctx.matched + 1;
1032
        k
1033
      | _ -> fail loc "typ_kind_open")
67✔
1034
;;
1035

1036
let typ_kind_variant =
1037
  T
1038
    (fun ctx loc x k ->
1039
      match x with
59✔
1040
      | Typedtree.Ttype_variant _ ->
49✔
1041
        ctx.matched <- ctx.matched + 1;
1042
        k
1043
      | _ -> fail loc "typ_kind_variant")
10✔
1044
;;
1045

1046
let typ_kind_record (T flabels) =
1047
  T
55✔
1048
    (fun ctx loc x k ->
1049
      match x with
10✔
1050
      | Typedtree.Ttype_record labels ->
10✔
1051
        ctx.matched <- ctx.matched + 1;
1052
        k |> flabels ctx loc labels
1053
      | _ -> fail loc "typ_kind_record")
×
1054
;;
1055

1056
(* Structure *)
1057

1058
let tstr_attribute (T fattr) =
1059
  T
40✔
1060
    (fun ctx loc str k ->
1061
      match str.str_desc with
40✔
1062
      | Tstr_attribute attr ->
15✔
1063
        ctx.matched <- ctx.matched + 1;
1064
        k |> fattr ctx loc attr
1065
      | _ -> fail loc "tstr_attribute")
25✔
1066
;;
1067

1068
let tsig_attribute (T fattr) =
1069
  T
3✔
1070
    (fun ctx loc str k ->
1071
      match str.sig_desc with
3✔
1072
      | Tsig_attribute attr ->
2✔
1073
        ctx.matched <- ctx.matched + 1;
1074
        k |> fattr ctx loc attr
1075
      | _ -> fail loc "tsig_attribute")
1✔
1076
;;
1077

1078
let tsig_val_name (T fname) =
1079
  T
×
1080
    (fun ctx loc str k ->
1081
      match str.sig_desc with
×
1082
      | Tsig_value { val_id = txt } ->
×
1083
        ctx.matched <- ctx.matched + 1;
1084
        k |> fname ctx loc txt
1085
      | _ -> fail loc "tsig_val_name")
×
1086
;;
1087

1088
let attribute (T fname) (T fpayload) =
1089
  T
43✔
1090
    (fun ctx loc attr k ->
1091
      let open Parsetree in
17✔
1092
      k |> fname ctx loc attr.attr_name.txt |> fpayload ctx loc attr.attr_payload)
17✔
1093
;;
1094

1095
let payload_stru (T fstru) =
1096
  T
43✔
1097
    (fun ctx loc x k ->
1098
      match x with
17✔
1099
      | Parsetree.PStr stru -> k |> fstru ctx loc stru
17✔
1100
      | _ -> fail loc "payload_stru")
×
1101
;;
1102

1103
let pstr_eval (T f) =
1104
  T
43✔
1105
    (fun ctx loc x k ->
1106
      match x.Parsetree.pstr_desc with
17✔
1107
      | Parsetree.Pstr_eval (e, _) -> k |> f ctx loc e
17✔
1108
      | _ -> fail loc "pstr_eval")
×
1109
;;
1110

1111
let pexp_constant (T f) =
1112
  T
43✔
1113
    (fun ctx loc e k ->
1114
      match e.Parsetree.pexp_desc with
17✔
1115
      | Parsetree.Pexp_constant e -> k |> f ctx loc e
13✔
1116
      | _ -> fail loc "pexp_constant")
4✔
1117
;;
1118

1119
[%%if ocaml_version < (5, 0, 0)]
1120

1121
let pexp_function_cases (T fargs) (T fcases) =
1122
  let open Parsetree in
3✔
1123
  let rec helper acc ctx loc x k =
1124
    match x.pexp_desc with
9✔
1125
    | Pexp_fun (Asttypes.Nolabel, None, pat, rhs) -> helper (pat :: acc) ctx loc rhs k
6✔
1126
    | Pexp_function cases -> k |> fargs ctx loc (List.rev acc) |> fcases ctx loc cases
3✔
1127
    | _ -> fail loc "pexp_function_cases"
×
1128
  in
1129
  T (helper [])
3✔
1130
;;
1131

1132
let pexp_function_body (T fargs) (T fcases) =
1133
  let open Parsetree in
1✔
1134
  let rec helper acc ctx loc x k =
1135
    match x.pexp_desc with
3✔
1136
    | Pexp_fun (Asttypes.Nolabel, None, pat, rhs) -> helper (pat :: acc) ctx loc rhs k
2✔
1137
    | _ -> k |> fargs ctx loc (List.rev acc) |> fcases ctx loc x
1✔
1138
  in
1139
  T (helper [])
1✔
1140
;;
1141

1142
let pconst_string (T fstring) =
1143
  T
43✔
1144
    (fun ctx loc x k ->
1145
      match x with
13✔
1146
      | Parsetree.Pconst_string (s, _, _) -> k |> fstring ctx loc s
13✔
1147
      | _ -> fail loc "pconst_string")
×
1148
;;
1149

1150
[%%else]
1151

1152
let pexp_function_body (T fargs) (T fbody) =
1153
  let open Parsetree in
1154
  T
1155
    (fun ctx loc x k ->
1156
      match x.pexp_desc with
1157
      | Pexp_function (params, _, Pfunction_body e) ->
1158
        let args =
1159
          List.map
1160
            (fun p ->
1161
              match p.pparam_desc with
1162
              | Pparam_val (Nolabel, _, pat) -> pat
1163
              | Pparam_newtype _ | _ -> fail loc "pexp_function_body: params")
1164
            params
1165
        in
1166
        k |> fargs ctx loc args |> fbody ctx loc e
1167
      | _ -> fail loc "pexp_function_body")
1168
;;
1169

1170
let pexp_function_cases (T fargs) (T fcases) =
1171
  let open Parsetree in
1172
  T
1173
    (fun ctx loc x k ->
1174
      match x.pexp_desc with
1175
      | Pexp_function (params, _, Pfunction_cases (cases, _, _)) ->
1176
        let args =
1177
          List.map
1178
            (fun p ->
1179
              match p.pparam_desc with
1180
              | Pparam_val (Nolabel, _, pat) -> pat
1181
              | Pparam_newtype _ | _ -> fail loc "pexp_function_cases: params")
1182
            params
1183
        in
1184
        k |> fargs ctx loc args |> fcases ctx loc cases
1185
      | _ -> fail loc "pexp_function_cases")
1186
;;
1187

1188
let pconst_string (T fstring) =
1189
  T
1190
    (fun ctx loc x k ->
1191
      match x.Parsetree.pconst_desc with
1192
      | Parsetree.Pconst_string (s, _, _) -> k |> fstring ctx loc s
1193
      | _ -> fail loc "pconst_string")
1194
;;
1195

1196
[%%endif]
1197

1198
let pexp_apply (T f) (T fargs) =
1199
  let open Parsetree in
1✔
1200
  let helper ctx loc x k =
1201
    match x.pexp_desc with
1✔
1202
    | Pexp_apply (efun, eargs) -> k |> f ctx loc efun |> fargs ctx loc eargs
1✔
1203
    | _ -> fail loc "pexp_apply"
×
1204
  in
1205
  T helper
1206
;;
1207

1208
let tstr_docattr on_str =
1209
  tstr_attribute
40✔
1210
    (attribute
40✔
1211
       drop
1212
       (payload_stru (pstr_eval (pexp_constant (pconst_string on_str)) ^:: nil)))
40✔
1213
;;
1214

1215
let tsig_docattr on_str =
1216
  tsig_attribute
3✔
1217
    (attribute
3✔
1218
       drop
1219
       (payload_stru (pstr_eval (pexp_constant (pconst_string on_str)) ^:: nil)))
3✔
1220
;;
1221

1222
type context = Ast_pattern0.context
1223

1224
let of_func f = T f
×
1225
let to_func (T f) = f
×
1226
let fail = fail
1227

1228
let%test_module "Fake tests, only to increase coverage" =
1229
  (module struct
1230
    [@@@coverage off]
1231

1232
    let noloc =
1233
      Warnings.
1234
        { loc_start = Lexing.dummy_pos; loc_end = Lexing.dummy_pos; loc_ghost = true }
1235
    ;;
1236

1237
    let%test _ =
1238
      match path_of_list [] with
1239
      | exception Failure _ -> true
1240
      | _ -> false
1241
    ;;
1242

1243
    let%test_unit _ =
1244
      let mk p ?(inv = false) what =
1245
        let on_error, rez =
1246
          if inv then Fun.const true, false else Fun.const false, true
1247
        in
1248
        parse p noloc ~on_error what rez
1249
      in
1250
      [%test_eq: Base.bool]
1251
        true
1252
        (mk
1253
           ~inv:true
1254
           (path_pident drop)
1255
           Path.(Pdot (Pident (Ident.create_local "List"), "map")));
1256
      [%test_eq: Base.bool]
1257
        true
1258
        (mk (path_pident drop) Path.(Pident (Ident.create_local "compare")));
1259
      [%test_eq: Base.bool] true (mk ~inv:true (labelled drop) Asttypes.Nolabel);
1260
      [%test_eq: Base.bool]
1261
        true
1262
        (mk
1263
           (econst drop)
1264
           { Typedtree.exp_desc = Texp_constant (Asttypes.Const_string ("", noloc, None))
1265
           ; exp_extra = []
1266
           ; exp_type = Predef.type_string
1267
           ; exp_loc = noloc
1268
           ; exp_env = Env.empty
1269
           ; exp_attributes = []
1270
           });
1271
      let _42 =
1272
        { Typedtree.exp_desc = Texp_constant (Asttypes.Const_int 42)
1273
        ; exp_extra = []
1274
        ; exp_type = Predef.type_int
1275
        ; exp_loc = noloc
1276
        ; exp_env = Env.empty
1277
        ; exp_attributes = []
1278
        }
1279
      in
1280
      [%test_eq: Base.bool] true (mk (econst drop) _42)
1281
    ;;
1282
  end)
1283
;;
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