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

Kakadu / zanuda / 66

18 Jun 2026 12:48PM UTC coverage: 83.301% (+0.3%) from 82.988%
66

push

github

Kakadu
ci: reenable coverage calculation for 4.14

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

2170 of 2605 relevant lines covered (83.3%)

553.79 hits per line

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

76.72
/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))
76,461✔
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,252✔
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
133,921✔
44
let restore_context ctx backup = ctx.matched <- backup
88,118✔
45
let incr_matched c = c.matched <- c.matched + 1
4,239✔
46

47
let parse (T f) loc ?on_error x k =
48
  try f { matched = 0 } loc x k with
1,634✔
49
  | Expected (loc, expected) ->
31,847✔
50
    (match on_error with
51
     | None -> Location.raise_errorf ~loc "%s expected" expected
×
52
     | Some f -> f expected)
31,847✔
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,901✔
66
      k x)
2,901✔
67
;;
68

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

77
let pair (T f1) (T f2) =
78
  T
10,104✔
79
    (fun ctx loc (x1, x2) k ->
80
      let k = f1 ctx loc x1 k in
411✔
81
      let k = f2 ctx loc x2 k in
392✔
82
      k)
264✔
83
;;
84

85
let ( ** ) = pair
86

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

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

101
let ( +?? ) (T fargs) msg =
102
  T
×
103
    (fun ctx loc e k ->
104
      try fargs ctx loc e k with
×
105
      | Ast_pattern0.Expected (loc, _) -> fail loc msg)
×
106
;;
107

108
let cst ~to_string ?(equal = Stdlib.( = )) v =
6,215✔
109
  T
6,215✔
110
    (fun ctx loc x k ->
111
      if equal x v
190✔
112
      then (
64✔
113
        incr_matched ctx;
114
        (* printf "cst succeeded for %s\n%!" (to_string v); *)
115
        k)
64✔
116
      else fail loc (to_string v))
126✔
117
;;
118

119
let int v = cst ~to_string:Int.to_string v
470✔
120
let char v = cst ~to_string:(Printf.sprintf "%C") v
×
121
let string v = cst ~to_string:(Printf.sprintf "%S") v
5,745✔
122
let float v = cst ~to_string:Float.to_string v
×
123
let int32 v = cst ~to_string:Int32.to_string v
×
124
let int64 v = cst ~to_string:Int64.to_string v
×
125
let nativeint v = cst ~to_string:Nativeint.to_string v
×
126
let bool v = cst ~to_string:Bool.to_string v
×
127

128
let false_ =
129
  T
130
    (fun ctx loc x k ->
131
      match x with
×
132
      | false ->
×
133
        ctx.matched <- ctx.matched + 1;
134
        k
135
      | _ -> fail loc "false")
×
136
;;
137

138
let true_ =
139
  T
140
    (fun ctx loc x k ->
141
      match x with
×
142
      | true ->
×
143
        ctx.matched <- ctx.matched + 1;
144
        k
145
      | _ -> fail loc "true")
×
146
;;
147

148
let nil =
149
  T
150
    (fun ctx loc x k ->
151
      log "trying [] \n%!";
442✔
152
      match x with
442✔
153
      | [] ->
346✔
154
        ctx.matched <- ctx.matched + 1;
155
        k
156
      | _ -> fail loc "[]")
96✔
157
;;
158

159
let ( ^:: ) (T f0) (T f1) =
160
  T
24,322✔
161
    (fun ctx loc x k ->
162
      match x with
715✔
163
      | x0 :: x1 ->
656✔
164
        ctx.matched <- ctx.matched + 1;
165
        (* Format.printf "trying elem of cons cell\n%!"; *)
166
        let k = f0 ctx loc x0 k in
167
        (* Format.printf "trying tail of cons cell\n%!"; *)
168
        let k = f1 ctx loc x1 k in
550✔
169
        (* Format.printf "trying  cons cell succeeded\n%!"; *)
170
        k
402✔
171
      | _ ->
59✔
172
        (* Format.printf "failing elem of cons cell\n%!"; *)
173
        fail loc "::")
174
;;
175

176
let list (T fel) =
177
  let rec helper acc ctx loc xs k =
2✔
178
    match xs with
6✔
179
    | [] -> k (List.rev acc)
2✔
180
    | h :: tl ->
4✔
181
      (match fel ctx loc h Fun.id with
182
       | x -> helper (x :: acc) ctx loc tl k)
4✔
183
  in
184
  T (fun ctx loc xs k -> helper [] ctx loc xs k)
2✔
185
;;
186

187
let none =
188
  T
189
    (fun ctx loc x k ->
190
      match x with
68✔
191
      | None ->
68✔
192
        ctx.matched <- ctx.matched + 1;
193
        k
194
      | _ -> fail loc "None")
×
195
;;
196

197
let some (T f0) =
198
  T
8,786✔
199
    (fun ctx loc x k ->
200
      match x with
152✔
201
      | Some x0 ->
152✔
202
        ctx.matched <- ctx.matched + 1;
203
        let k = f0 ctx loc x0 k in
204
        k
71✔
205
      | _ -> fail loc "Some")
×
206
;;
207

208
let triple (T f1) (T f2) (T f3) =
209
  T
×
210
    (fun ctx loc (x1, x2, x3) k ->
211
      let k = f1 ctx loc x1 k in
×
212
      let k = f2 ctx loc x2 k in
×
213
      let k = f3 ctx loc x3 k in
×
214
      k)
×
215
;;
216

217
let alt (T f1) (T f2) =
218
  T
13,006✔
219
    (fun ctx loc x k ->
220
      let backup = save_context ctx in
45,452✔
221
      try f1 ctx loc x k with
838✔
222
      | e1 ->
44,614✔
223
        let m1 = save_context ctx in
224
        restore_context ctx backup;
44,614✔
225
        (try f2 ctx loc x k with
759✔
226
         | e2 ->
43,855✔
227
           let m2 = save_context ctx in
228
           if m1 >= m2
43,855✔
229
           then (
43,504✔
230
             restore_context ctx m1;
231
             raise e1)
43,504✔
232
           else raise e2))
351✔
233
;;
234

235
let ( ||| ) = alt
236

237
let conde = function
238
  | [] -> fail Location.none "Bad argument"
×
239
  | h :: tl -> List.fold_left ( ||| ) h tl
31✔
240
;;
241

242
let map (T func) ~f = T (fun ctx loc x k -> func ctx loc x (f k))
×
243
let map' (T func) ~f = T (fun ctx loc x k -> func ctx loc x (f loc k))
×
244
let map_result (T func) ~f = T (fun ctx loc x k -> f (func ctx loc x k))
×
245
let ( >>| ) t f = map t ~f
×
246
let map0 (T func) ~f = T (fun ctx loc x k -> func ctx loc x (k f))
348✔
247
let map1 (T func) ~f = T (fun ctx loc x k -> func ctx loc x (fun a -> k (f a)))
610✔
248
let map2 (T func) ~f = T (fun ctx loc x k -> func ctx loc x (fun a b -> k (f a b)))
371✔
249
let map3 (T func) ~f = T (fun ctx loc x k -> func ctx loc x (fun a b c -> k (f a b c)))
61✔
250

251
let map4 (T func) ~f =
252
  T (fun ctx loc x k -> func ctx loc x (fun a b c d -> k (f a b c d)))
7✔
253
;;
254

255
let map5 (T func) ~f =
256
  T (fun ctx loc x k -> func ctx loc x (fun a b c d e -> k (f a b c d e)))
22✔
257
;;
258

259
let map6 (T func) ~f:fmap =
260
  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✔
261
;;
262

263
let map7 (T func) ~f:fmap =
264
  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✔
265
;;
266

267
let map0' (T func) ~f = T (fun ctx loc x k -> func ctx loc x (k (f loc)))
×
268
let map1' (T func) ~f = T (fun ctx loc x k -> func ctx loc x (fun a -> k (f loc a)))
×
269
let map2' (T func) ~f = T (fun ctx loc x k -> func ctx loc x (fun a b -> k (f loc a b)))
×
270
let map_result (T func) ~f = T (fun ctx loc x k -> f (func ctx loc x k))
×
271
let alt_option some none = alt (map1 some ~f:(fun x -> Some x)) (map0 none ~f:None)
×
272

273
let many (T f) =
274
  T (fun ctx loc l k -> k (ListLabels.map l ~f:(fun x -> f ctx loc x (fun x -> x))))
×
275
;;
276

277
let loc (T f) = T (fun ctx _loc (x : _ Ppxlib.Loc.t) k -> f ctx x.loc x.txt k)
×
278
let pack0 t = map t ~f:(fun f -> f ())
×
279
let pack2 t = map t ~f:(fun f x y -> f (x, y))
×
280
let pack3 t = map t ~f:(fun f x y z -> f (x, y, z))
×
281

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

285
let lident (T fident) =
286
  T
667✔
287
    (fun ctx loc x k ->
288
      match x with
145✔
289
      | Longident.Lident id ->
135✔
290
        ctx.matched <- ctx.matched + 1;
291
        k |> fident ctx loc id
292
      | _ -> fail loc "lident")
10✔
293
;;
294

295
let elongident (lident : Longident.t) =
296
  T
59✔
297
    (fun ctx loc x k ->
298
      if Stdlib.compare x lident = 0
231✔
299
      then (
24✔
300
        ctx.matched <- ctx.matched + 1;
301
        k)
302
      else fail loc "elongident")
207✔
303
;;
304

305
let path_pident (T fident) =
306
  T
2✔
307
    (fun ctx loc x k ->
308
      match x with
2✔
309
      | Path.Pident id ->
1✔
310
        ctx.matched <- ctx.matched + 1;
311
        k |> fident ctx loc id
312
      | _ -> fail loc "path_pident")
1✔
313
;;
314

315
let path xs =
316
  let rec helper ps ctx loc x k =
5,759✔
317
    let cmp_names l r =
14,715✔
318
      let ans = String.equal l r in
8,113✔
319
      (* printf "\t\tCompare names %s and %s:  %b\n%!" l r ans; *)
320
      ans
8,113✔
321
    in
322
    match x, ps with
323
    | Path.Pident id, [ id0 ] ->
118✔
324
      if cmp_names (Ident.name id) id0
118✔
325
      then (
111✔
326
        let () = ctx.matched <- ctx.matched + 1 in
327
        k)
328
      else fail loc "path"
7✔
329
    | Path.Pdot (next, id), id0 :: ids when cmp_names id id0 -> helper ids ctx loc next k
159✔
330
    | Path.Papply _, _ -> fail loc "path got Papply"
×
331
    | _ -> fail loc (sprintf "path %s" (String.concat "." xs))
14,438✔
332
  in
333
  T (helper (List.rev xs))
5,759✔
334
;;
335

336
let path_of_list = function
337
  | [] -> failwith "Bad argument: path_of_list"
1✔
338
  | s :: tl ->
2✔
339
    ListLabels.fold_left
340
      tl
341
      ~init:(Path.Pident (Ident.create_local s))
2✔
342
      ~f:(fun acc x -> Path.Pdot (acc, x))
4✔
343
;;
344

345
let%test_module " " =
346
  (module struct
347
    [@@@coverage off]
348

349
    let names = [ "Stdlib!"; "List"; "length" ]
350

351
    [%%if ocaml_version < (5, 0, 0)]
352

353
    let pp_path = Path.print
354

355
    [%%else]
356

357
    let pp_path = Format_doc.compat Path.print
358

359
    [%%endif]
360

361
    let%test_unit _ =
362
      let old = !Clflags.unique_ids in
363
      Clflags.unique_ids := false;
364
      [%test_eq: Base.string]
365
        "Stdlib!.List.length"
366
        (asprintf "%a" pp_path (path_of_list names));
367
      Clflags.unique_ids := old
368
    ;;
369

370
    let%test _ =
371
      let noloc =
372
        Warnings.
373
          { loc_start = Lexing.dummy_pos; loc_end = Lexing.dummy_pos; loc_ghost = true }
374
      in
375
      parse (path names) noloc ~on_error:(fun _ -> false) (path_of_list names) true
376
    ;;
377
  end)
378
;;
379

380
open Typedtree
381

382
let econst (T f0) =
383
  T
2✔
384
    (fun ctx loc x k ->
385
      match x.exp_desc with
2✔
386
      | Texp_constant n ->
2✔
387
        ctx.matched <- ctx.matched + 1;
388
        f0 ctx loc n k
389
      | _ -> fail loc (sprintf "econst"))
×
390
;;
391

392
let eint (T f0) =
393
  T
470✔
394
    (fun ctx loc x k ->
395
      match x.exp_desc with
17✔
396
      | Texp_constant (Asttypes.Const_int n) ->
8✔
397
        ctx.matched <- ctx.matched + 1;
398
        f0 ctx loc n k
399
      | _ -> fail loc "eint")
9✔
400
;;
401

402
let estring =
403
  T
404
    (fun ctx loc x k ->
405
      match x.exp_desc with
24✔
406
      | Texp_constant (Asttypes.Const_string (s, _, None)) ->
24✔
407
        ctx.matched <- ctx.matched + 1;
408
        k s
409
      | _ -> fail loc "estring")
×
410
;;
411

412
let ebool =
413
  T
414
    (fun ctx loc x k ->
415
      match x.exp_desc with
83✔
416
      | Texp_construct ({ txt = Lident "true" }, _, []) ->
10✔
417
        ctx.matched <- ctx.matched + 1;
418
        k true
419
      | Texp_construct ({ txt = Lident "false" }, _, []) ->
5✔
420
        ctx.matched <- ctx.matched + 1;
421
        k false
422
      | _ -> fail loc (sprintf "ebool"))
68✔
423
;;
424

425
[%%if ocaml_version < (5, 0, 0)]
426

427
let tpat_var (T fname) =
428
  T
1,667✔
429
    (fun ctx loc x k ->
430
      match x.pat_desc with
61✔
431
      | Tpat_var (_, { txt }) ->
61✔
432
        ctx.matched <- ctx.matched + 1;
433
        k |> fname ctx loc txt
434
      | _ -> fail loc "tpat_var")
×
435
;;
436

437
let tpat_id (T fname) =
438
  T
2,143✔
439
    (fun ctx loc x k ->
440
      match x.pat_desc with
374✔
441
      | Tpat_var (id, { loc }) ->
302✔
442
        ctx.matched <- ctx.matched + 1;
443
        k |> fname ctx loc id
444
      | _ -> fail loc "tpat_var_id")
72✔
445
;;
446

447
[%%else]
448

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

465
let tpat_id (T fname) =
466
  T
467
    (fun (type kind) ctx loc (x : kind pattern_desc pattern_data) k ->
468
      match x.pat_desc with
469
      | Typedtree.Tpat_value v ->
470
        (match (v :> pattern).pat_desc with
471
         | Tpat_var (id, { loc }, _uid) ->
472
           ctx.matched <- ctx.matched + 1;
473
           k |> fname ctx loc id
474
         | _ -> fail loc "tpat_id")
475
      | Tpat_var (id, { loc }, _uid) ->
476
        ctx.matched <- ctx.matched + 1;
477
        k |> fname ctx loc id
478
      | _ -> fail loc "tpat_id 2")
479
;;
480

481
[%%endif]
482

483
let tpat_constructor (T fname) (T fargs) =
484
  T
5,960✔
485
    (fun ctx loc x k ->
486
      match x.pat_desc with
84✔
487
      | Tpat_construct ({ txt }, _, args, _) ->
72✔
488
        ctx.matched <- ctx.matched + 1;
489
        k |> fname ctx loc txt |> fargs ctx loc args
62✔
490
      | _ -> fail loc "tpat_constructor")
12✔
491
;;
492

493
let tpat_tuple (T fargs) =
494
  T
×
495
    (fun ctx loc x k ->
496
      match x.pat_desc with
×
497
      | Tpat_tuple pats ->
×
498
        ctx.matched <- ctx.matched + 1;
499
        k |> fargs ctx loc pats
500
      | _ -> fail loc "tpat_tuple")
×
501
;;
502

503
let tpat_value (T fpat) =
504
  T
×
505
    (fun ctx loc x k ->
506
      match x.pat_desc with
×
507
      | Tpat_value arg ->
×
508
        let inner = (arg :> value pattern_desc pattern_data) in
509
        ctx.matched <- ctx.matched + 1;
510
        k |> fpat ctx loc inner
511
      | _ -> fail loc "tpat_value")
×
512
;;
513

514
let tpat_exception (T fpat) =
515
  T
×
516
    (fun ctx loc x k ->
517
      match x.pat_desc with
×
518
      | Tpat_exception exc ->
×
519
        ctx.matched <- ctx.matched + 1;
520
        k |> fpat ctx loc exc
521
      | _ -> fail loc "tpat_exception")
×
522
;;
523

524
let tpat_any =
525
  T
526
    (fun ctx loc x k ->
527
      match x.pat_desc with
3✔
528
      | Tpat_any ->
2✔
529
        ctx.matched <- ctx.matched + 1;
530
        k
531
      | _ -> fail loc "tpat_any")
1✔
532
;;
533

534
let texp_ident (T fpath) =
535
  T
15,547✔
536
    (fun ctx loc x k ->
537
      let __ _ = log "texp_ident %a\n%!" My_printtyped.expr x in
×
538
      match x.exp_desc with
539
      | Texp_ident (path, _, _) ->
12,831✔
540
        ctx.matched <- ctx.matched + 1;
541
        let ans = fpath ctx loc path k in
542
        log "texp_ident + %a\n%!" My_printtyped.expr x;
810✔
543
        ans
810✔
544
      | _ -> fail loc "texp_ident")
3,518✔
545
;;
546

547
let texp_ident_loc (T fpath) =
548
  T
1,385✔
549
    (fun ctx loc x k ->
550
      match x.exp_desc with
10✔
551
      | Texp_ident (path, _, _) ->
5✔
552
        ctx.matched <- ctx.matched + 1;
553
        k x.exp_loc |> fpath ctx loc path
5✔
554
      | _ -> fail loc "texp_ident")
5✔
555
;;
556

557
(* TODO(Kakadu): accept and Ident, and not a string *)
558
let pident (T fstr) =
559
  T
8,149✔
560
    (fun ctx loc x k ->
561
      match x with
231✔
562
      | Path.Pident id -> fstr ctx loc (Ident.name id) k
96✔
563
      | _ -> fail loc "pident")
135✔
564
;;
565

566
let texp_ident_typ (T fpath) (T ftyp) =
567
  T
294✔
568
    (fun ctx loc x k ->
569
      (* let __ _ = Format.printf "texp_ident_typ %a\n%!" MyPrinttyped.expr x in *)
570
      match x.exp_desc with
1,781✔
571
      | Texp_ident (path, _, typ) ->
904✔
572
        ctx.matched <- ctx.matched + 1;
573
        k |> fpath ctx loc path |> ftyp ctx loc typ.Types.val_type
472✔
574
      | _ -> fail loc "texp_ident_typ")
877✔
575
;;
576

577
[%%if ocaml_version < (5, 0, 0)]
578

579
let texp_assert (T fexp) =
580
  T
59✔
581
    (fun ctx loc x k ->
582
      match x.exp_desc with
1,595✔
583
      | Texp_assert e ->
1✔
584
        ctx.matched <- ctx.matched + 1;
585
        fexp ctx loc e k
586
      | _ -> fail loc "texp_assert")
1,594✔
587
;;
588

589
[%%else]
590

591
let texp_assert (T fexp) =
592
  T
593
    (fun ctx loc x k ->
594
       match x.exp_desc with
595
       | Texp_assert (e, _) ->
596
         ctx.matched <- ctx.matched + 1;
597
         fexp ctx loc e k
598
       | _ -> fail loc "texp_assert"
599
     : context -> Warnings.loc -> expression -> 'a -> 'b)
600
;;
601

602
[%%endif]
603

604
let texp_apply (T f0) (T args0) =
605
  T
6,410✔
606
    (fun ctx loc x k ->
607
      (* let __ _ = log "texp_apply %a\n%!" MyPrinttyped.expr x in *)
608
      match x.exp_desc with
27,945✔
609
      | Texp_apply (f, args) ->
3,979✔
610
        ctx.matched <- ctx.matched + 1;
611
        let ans = k |> f0 ctx loc f |> args0 ctx loc args in
72✔
612
        (* let _ = log "texp_apply + %a\n%!" MyPrinttyped.expr x in *)
613
        ans
43✔
614
      | _ -> fail loc "texp_apply")
23,966✔
615
;;
616

617
let texp_apply_nolabelled (T f0) (T args0) =
618
  let exception EarlyExit in
1,579✔
619
  T
620
    (fun ctx loc x k ->
621
      match x.exp_desc with
3,358✔
622
      | Texp_apply (f, args) ->
534✔
623
        ctx.matched <- ctx.matched + 1;
624
        let k = f0 ctx loc f k in
625
        (try
103✔
626
           let args =
627
             ListLabels.map args ~f:(function
628
               | Asttypes.Labelled _, _ | Asttypes.Optional _, _ | _, None ->
×
629
                 raise EarlyExit
630
               | _, Some x -> x)
216✔
631
           in
632
           args0 ctx loc args k
27✔
633
         with
634
         | EarlyExit -> fail loc "texp_apply: None among the arguments ")
2✔
635
      | _ -> fail loc "texp_apply")
2,824✔
636
;;
637

638
let texp_construct (T fpath) (T fcd) (T fargs) =
639
  T
242✔
640
    (fun ctx loc x k ->
641
      match x.exp_desc with
1,623✔
642
      | Texp_construct (path, cd, args) ->
244✔
643
        ctx.matched <- ctx.matched + 1;
644
        let k = fpath ctx loc path.txt k in
645
        k |> fcd ctx loc cd |> fargs ctx loc args
37✔
646
      | _ -> fail loc (sprintf "texp_construct"))
1,379✔
647
;;
648

649
let texp_assert_false () = texp_assert (texp_construct (lident (string "false")) drop nil)
59✔
650

651
let texp_let (T fvbs) (T fexpr) =
652
  T
1,608✔
653
    (fun ctx loc x k ->
654
      match x.exp_desc with
1,400✔
655
      | Texp_let (_flg, vbs, expr) ->
19✔
656
        ctx.matched <- ctx.matched + 1;
657
        k |> fvbs ctx loc vbs |> fexpr ctx loc expr
16✔
658
      | _ -> fail loc (sprintf "texp_let"))
1,381✔
659
;;
660

661
let nolabel =
662
  T
663
    (fun ctx loc x k ->
664
      match x with
256✔
665
      | Asttypes.Nolabel ->
237✔
666
        ctx.matched <- ctx.matched + 1;
667
        k
668
      | _ -> fail loc "nolabel")
19✔
669
;;
670

671
let labelled (T fstr) =
672
  T
60✔
673
    (fun ctx loc x k ->
674
      match x with
3✔
675
      | Asttypes.Labelled s ->
2✔
676
        ctx.matched <- ctx.matched + 1;
677
        k |> fstr ctx loc s
678
      | _ -> fail loc "labelled")
1✔
679
;;
680

681
let texp_apply1 f x = texp_apply f ((nolabel ** some x) ^:: nil)
3,680✔
682
let texp_apply2 f x y = texp_apply f ((nolabel ** some x) ^:: (nolabel ** some y) ^:: nil)
2,317✔
683

684
[%%if ocaml_version < (4, 11, 2)]
685

686
(* 4.10 *)
687
type case_val = Typedtree.case
688
type case_comp = Typedtree.case
689
type value_pat = pattern
690
type comp_pat = pattern
691

692
[%%else]
693

694
type case_val = value case
695
type case_comp = computation case
696
type value_pat = value pattern_desc pattern_data
697
type comp_pat = computation pattern_desc pattern_data
698

699
[%%endif]
700
[%%if ocaml_version < (5, 0, 0)]
701

702
let texp_function (T fcases) =
703
  T
×
704
    (fun ctx loc e k ->
705
      match e.exp_desc with
×
706
      | Texp_function { cases } ->
×
707
        ctx.matched <- ctx.matched + 1;
708
        k |> fcases ctx loc cases
709
      | _ -> fail loc "texp_function")
×
710
;;
711

712
let texp_function_body (T fargs) (T frhs) =
713
  let rec helper acc ctx loc e k =
7,290✔
714
    match e.exp_desc with
6,673✔
715
    | Texp_function
989✔
716
        { cases =
717
            [ { c_lhs = { pat_desc = Tpat_var (pid, _); pat_loc; _ }
718
              ; c_rhs
719
              ; c_guard = None
720
              }
721
            ]
722
        ; arg_label
723
        ; partial = Total
724
        } -> helper ((arg_label, (pid, pat_loc)) :: acc) ctx loc c_rhs k
725
    | _ when [] = acc -> fail loc "texp_function_body"
4,962✔
726
    | _ -> k |> fargs ctx loc (List.rev acc) |> frhs ctx loc e
623✔
727
  in
728
  T (helper [])
7,290✔
729
;;
730

731
let texp_function_cases
732
  :  ((Asttypes.arg_label * (Ident.t * Location.t)) list, 'a, 'b) t
733
  -> (value case list, 'b, 'c) t
734
  -> (expression, 'a, 'c) t
735
  =
736
  fun (T fargs) (T frhs) ->
737
  let rec helper acc ctx loc e k =
6,300✔
738
    match e.exp_desc with
5,104✔
739
    | Typedtree.Texp_function
598✔
740
        { cases =
741
            [ { c_lhs = { pat_desc = Tpat_var (pid, tag); _ }; c_rhs; c_guard = _ } ]
742
        ; arg_label
743
        ; partial = Total
744
        } -> helper ((arg_label, (pid, tag.loc)) :: acc) ctx loc c_rhs k
745
    | Texp_function { cases = _ :: _ :: _ as cases; _ } ->
106✔
746
      k |> fargs ctx loc (List.rev acc) |> frhs ctx loc cases
68✔
747
    | _ -> fail loc "texp_function_cases"
4,400✔
748
  in
749
  T (helper [])
6,300✔
750
;;
751

752
[%%else]
753

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

769
let texp_function_body (T fparam) (T fcases) =
770
  T
771
    (fun ctx loc e k ->
772
      match e.exp_desc with
773
      | Typedtree.Texp_function (params, Tfunction_body e) ->
774
        ctx.matched <- ctx.matched + 1;
775
        k
776
        |> fparam
777
             ctx
778
             loc
779
             (List.map (fun p -> p.fp_arg_label, (p.fp_param, p.fp_loc)) params)
780
        |> fcases ctx loc e
781
      | _ -> fail loc "texp_function")
782
;;
783

784
[%%endif]
785

786
let case (T pat) (T guard) (T rhs) =
787
  T
7,624✔
788
    (fun ctx loc { c_lhs; c_rhs; c_guard } k ->
789
      k |> pat ctx loc c_lhs |> guard ctx loc c_guard |> rhs ctx loc c_rhs)
49✔
790
;;
791

792
let ccase (T pat) (T guard) (T rhs) =
793
  T
×
794
    (fun ctx loc { c_lhs; c_rhs; c_guard } k ->
795
      k |> pat ctx loc c_lhs |> guard ctx loc c_guard |> rhs ctx loc c_rhs)
×
796
;;
797

798
[%%if ocaml_version < (5, 0, 0)]
799

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

863
[%%else]
864

865
let texp_match (T fexpr) (T fcomp_cases) (T fval_cases) =
866
  T
867
    (fun ctx loc e k ->
868
      match e.Typedtree.exp_desc with
869
      | Texp_match (e, ccases, vcases, _) ->
870
        let ccases, vcases =
871
          List.fold_left
872
            (fun (cacc, vacc) c ->
873
              match c.c_lhs.pat_desc with
874
              | Tpat_value v ->
875
                cacc, { c with c_lhs = (v :> value general_pattern) } :: vacc
876
              | _ -> cacc, vacc)
877
            ([], vcases)
878
            ccases
879
        in
880
        ctx.matched <- ctx.matched + 1;
881
        k |> fexpr ctx loc e |> fcomp_cases ctx loc ccases |> fval_cases ctx loc vcases
882
      | _ -> fail loc "texp_match")
883
;;
884

885
[%%endif]
886

887
let texp_ite (T pred) (T fthen) (T felse) =
888
  T
708✔
889
    (fun ctx loc e k ->
890
      match e.exp_desc with
8,386✔
891
      | Texp_ifthenelse (p, thenb, elseb) ->
179✔
892
        ctx.matched <- ctx.matched + 1;
893
        k |> pred ctx loc p |> fthen ctx loc thenb |> felse ctx loc elseb
75✔
894
      | _ -> fail loc "texp_ite")
8,207✔
895
;;
896

897
[%%if ocaml_version < (5, 0, 0)]
898

899
let texp_try (T fexpr) (T fcases) =
900
  T
59✔
901
    (fun ctx loc e k ->
902
      match e.exp_desc with
1,597✔
903
      | Texp_try (e, cases) ->
3✔
904
        ctx.matched <- ctx.matched + 1;
905
        k |> fexpr ctx loc e |> fcases ctx loc cases
3✔
906
      | _ -> fail loc "texp_try")
1,594✔
907
;;
908

909
[%%else]
910

911
let texp_try (T fexpr) (T fcases) =
912
  T
913
    (fun ctx loc e k ->
914
      match e.exp_desc with
915
      | Typedtree.Texp_try (e, cases, _) ->
916
        (* TODO: support effects *)
917
        ctx.matched <- ctx.matched + 1;
918
        k |> fexpr ctx loc e |> fcases ctx loc cases
919
      | _ -> fail loc "texp_try")
920
;;
921

922
[%%endif]
923

924
let texp_record (T fext) (T ffields) =
925
  T
1,605✔
926
    (fun ctx loc e k ->
927
      match e.exp_desc with
1,605✔
928
      | Texp_record { fields; extended_expression; _ } ->
19✔
929
        ctx.matched <- ctx.matched + 1;
930
        k |> fext ctx loc extended_expression |> ffields ctx loc fields
19✔
931
      | _ -> fail loc "texp_record")
1,586✔
932
;;
933

934
let texp_field (T fexpr) (T fdesc) =
935
  T
56✔
936
    (fun ctx loc e k ->
937
      match e.exp_desc with
51✔
938
      | Texp_field (e, _, desc) ->
17✔
939
        ctx.matched <- ctx.matched + 1;
940
        k |> fexpr ctx loc e |> fdesc ctx loc desc
17✔
941
      | _ -> fail loc "texp_field")
34✔
942
;;
943

944
let label_desc (T fname) =
945
  T
112✔
946
    (fun ctx loc e k ->
947
      match e with
95✔
948
      | { Types.lbl_name; _ } ->
95✔
949
        ctx.matched <- ctx.matched + 1;
950
        k |> fname ctx loc lbl_name)
951
;;
952

953
let rld_kept =
954
  T
955
    (fun ctx loc e k ->
956
      match e with
56✔
957
      | Kept _ ->
×
958
        ctx.matched <- ctx.matched + 1;
959
        k
960
      | _ -> fail loc "rld_kept")
56✔
961
;;
962

963
let rld_overriden (T flident) (T fexpr) =
964
  T
112✔
965
    (fun ctx loc e k ->
966
      match e with
95✔
967
      | Overridden ({ txt = lident }, e) ->
95✔
968
        ctx.matched <- ctx.matched + 1;
969
        k |> flident ctx loc lident |> fexpr ctx loc e
85✔
970
      | _ -> fail loc "rld_overriden")
×
971
;;
972

973
let value_binding (T fpat) (T fexpr) =
974
  T
1,794✔
975
    (fun ctx loc { vb_pat; vb_expr } k ->
976
      ctx.matched <- ctx.matched + 1;
196✔
977
      k |> fpat ctx loc vb_pat |> fexpr ctx loc vb_expr)
194✔
978
;;
979

980
(*   let hack0 (T path0) =
981
     T
982
     (fun ctx loc x k ->
983
     match x.Types.val_type.Types.desc with
984
     | Tconstr (path, [], _) ->
985
     ctx.matched <- ctx.matched + 1;
986
     path0 ctx loc path k
987
     | _ -> fail loc "hack0")
988
     ;;
989

990
     let hack1 ?(on_vd = drop) (T path0) =
991
     T
992
     (fun ctx loc x k ->
993
     match x.exp_desc with
994
     | Texp_ident (path, _, vd) ->
995
     ctx.matched <- ctx.matched + 1;
996
     let (T fvd) = on_vd in
997
     k |> path0 ctx loc path |> fvd ctx loc vd
998
     | _ -> fail loc "texp_ident")
999
     ;;
1000

1001
     let __ path = hack1 __ path *)
1002
let rec core_typ (T ftexpr) = T (fun ctx loc x k -> ftexpr ctx loc x.ctyp_type k)
175✔
1003

1004
let rec typ_constr (T fpath) (T fargs) =
1005
  let rec helper ctx loc x k =
697✔
1006
    (* Format.printf "typ = %a\n%!" Printtyp.type_expr x; *)
1007
    match Types.get_desc x with
2,568✔
1008
    | Tconstr (path, args, _) ->
1,332✔
1009
      ctx.matched <- ctx.matched + 1;
1010
      k |> fpath ctx loc path |> fargs ctx loc args
208✔
1011
    | Tlink arg -> helper ctx loc arg k
×
1012
    | _ -> fail loc "typ_constr"
1,236✔
1013
  in
1014
  T helper
1015
;;
1016

1017
let rec typ_arrow (T l) (T r) =
1018
  let rec helper ctx loc x k =
356✔
1019
    (* Format.printf "typ = %a\n%!" Printtyp.type_expr x; *)
1020
    match Types.get_desc x with
22✔
1021
    | Tarrow (_, tl, tr, _) ->
22✔
1022
      ctx.matched <- ctx.matched + 1;
1023
      k |> l ctx loc tl |> r ctx loc tr
22✔
1024
    | _ -> fail loc "typ_arrow"
×
1025
  in
1026
  T helper
1027
;;
1028

1029
let typ_kind_abstract =
1030
  T
1031
    (fun ctx loc x k ->
1032
      match x with
69✔
1033
      | Typedtree.Ttype_abstract ->
9✔
1034
        ctx.matched <- ctx.matched + 1;
1035
        k
1036
      | _ -> fail loc "typ_kind_abstract")
60✔
1037
;;
1038

1039
let typ_kind_open =
1040
  T
1041
    (fun ctx loc x k ->
1042
      match x with
69✔
1043
      | Typedtree.Ttype_open ->
×
1044
        ctx.matched <- ctx.matched + 1;
1045
        k
1046
      | _ -> fail loc "typ_kind_open")
69✔
1047
;;
1048

1049
let typ_kind_variant =
1050
  T
1051
    (fun ctx loc x k ->
1052
      match x with
60✔
1053
      | Typedtree.Ttype_variant _ ->
49✔
1054
        ctx.matched <- ctx.matched + 1;
1055
        k
1056
      | _ -> fail loc "typ_kind_variant")
11✔
1057
;;
1058

1059
let typ_kind_record (T flabels) =
1060
  T
57✔
1061
    (fun ctx loc x k ->
1062
      match x with
11✔
1063
      | Typedtree.Ttype_record labels ->
11✔
1064
        ctx.matched <- ctx.matched + 1;
1065
        k |> flabels ctx loc labels
1066
      | _ -> fail loc "typ_kind_record")
×
1067
;;
1068

1069
(* Structure *)
1070

1071
let tstr_attribute (T fattr) =
1072
  T
354✔
1073
    (fun ctx loc str k ->
1074
      match str.str_desc with
354✔
1075
      | Tstr_attribute attr ->
58✔
1076
        ctx.matched <- ctx.matched + 1;
1077
        k |> fattr ctx loc attr
1078
      | _ -> fail loc "tstr_attribute")
296✔
1079
;;
1080

1081
let tsig_attribute (T fattr) =
1082
  T
3✔
1083
    (fun ctx loc str k ->
1084
      match str.sig_desc with
3✔
1085
      | Tsig_attribute attr ->
2✔
1086
        ctx.matched <- ctx.matched + 1;
1087
        k |> fattr ctx loc attr
1088
      | _ -> fail loc "tsig_attribute")
1✔
1089
;;
1090

1091
let tsig_val_name (T fname) =
1092
  T
×
1093
    (fun ctx loc str k ->
1094
      match str.sig_desc with
×
1095
      | Tsig_value { val_id = txt } ->
×
1096
        ctx.matched <- ctx.matched + 1;
1097
        k |> fname ctx loc txt
1098
      | _ -> fail loc "tsig_val_name")
×
1099
;;
1100

1101
let attribute (T fname) (T fpayload) =
1102
  T
357✔
1103
    (fun ctx loc attr k ->
1104
      let open Parsetree in
60✔
1105
      k |> fname ctx loc attr.attr_name.txt |> fpayload ctx loc attr.attr_payload)
22✔
1106
;;
1107

1108
let payload_stru (T fstru) =
1109
  T
357✔
1110
    (fun ctx loc x k ->
1111
      match x with
22✔
1112
      | Parsetree.PStr stru -> k |> fstru ctx loc stru
22✔
1113
      | _ -> fail loc "payload_stru")
×
1114
;;
1115

1116
let pstr_eval (T f) =
1117
  T
357✔
1118
    (fun ctx loc x k ->
1119
      match x.Parsetree.pstr_desc with
22✔
1120
      | Parsetree.Pstr_eval (e, _) -> k |> f ctx loc e
22✔
1121
      | _ -> fail loc "pstr_eval")
×
1122
;;
1123

1124
let pexp_constant (T f) =
1125
  T
357✔
1126
    (fun ctx loc e k ->
1127
      match e.Parsetree.pexp_desc with
22✔
1128
      | Parsetree.Pexp_constant e -> k |> f ctx loc e
18✔
1129
      | _ -> fail loc "pexp_constant")
4✔
1130
;;
1131

1132
[%%if ocaml_version < (5, 0, 0)]
1133

1134
let pexp_function_cases (T fargs) (T fcases) =
1135
  let open Parsetree in
3✔
1136
  let rec helper acc ctx loc x k =
1137
    match x.pexp_desc with
9✔
1138
    | Pexp_fun (Asttypes.Nolabel, None, pat, rhs) -> helper (pat :: acc) ctx loc rhs k
6✔
1139
    | Pexp_function cases -> k |> fargs ctx loc (List.rev acc) |> fcases ctx loc cases
3✔
1140
    | _ -> fail loc "pexp_function_cases"
×
1141
  in
1142
  T (helper [])
3✔
1143
;;
1144

1145
let pexp_function_body (T fargs) (T fcases) =
1146
  let open Parsetree in
1✔
1147
  let rec helper acc ctx loc x k =
1148
    match x.pexp_desc with
3✔
1149
    | Pexp_fun (Asttypes.Nolabel, None, pat, rhs) -> helper (pat :: acc) ctx loc rhs k
2✔
1150
    | _ -> k |> fargs ctx loc (List.rev acc) |> fcases ctx loc x
1✔
1151
  in
1152
  T (helper [])
1✔
1153
;;
1154

1155
let pconst_string (T fstring) =
1156
  T
357✔
1157
    (fun ctx loc x k ->
1158
      match x with
18✔
1159
      | Parsetree.Pconst_string (s, _, _) -> k |> fstring ctx loc s
18✔
1160
      | _ -> fail loc "pconst_string")
×
1161
;;
1162

1163
[%%else]
1164

1165
let pexp_function_body (T fargs) (T fbody) =
1166
  let open Parsetree in
1167
  T
1168
    (fun ctx loc x k ->
1169
      match x.pexp_desc with
1170
      | Pexp_function (params, _, Pfunction_body e) ->
1171
        let args =
1172
          List.map
1173
            (fun p ->
1174
              match p.pparam_desc with
1175
              | Pparam_val (Nolabel, _, pat) -> pat
1176
              | Pparam_newtype _ | _ -> fail loc "pexp_function_body: params")
1177
            params
1178
        in
1179
        k |> fargs ctx loc args |> fbody ctx loc e
1180
      | _ -> fail loc "pexp_function_body")
1181
;;
1182

1183
let pexp_function_cases (T fargs) (T fcases) =
1184
  let open Parsetree in
1185
  T
1186
    (fun ctx loc x k ->
1187
      match x.pexp_desc with
1188
      | Pexp_function (params, _, Pfunction_cases (cases, _, _)) ->
1189
        let args =
1190
          List.map
1191
            (fun p ->
1192
              match p.pparam_desc with
1193
              | Pparam_val (Nolabel, _, pat) -> pat
1194
              | Pparam_newtype _ | _ -> fail loc "pexp_function_cases: params")
1195
            params
1196
        in
1197
        k |> fargs ctx loc args |> fcases ctx loc cases
1198
      | _ -> fail loc "pexp_function_cases")
1199
;;
1200

1201
let pconst_string (T fstring) =
1202
  T
1203
    (fun ctx loc x k ->
1204
      match x.Parsetree.pconst_desc with
1205
      | Parsetree.Pconst_string (s, _, _) -> k |> fstring ctx loc s
1206
      | _ -> fail loc "pconst_string")
1207
;;
1208

1209
[%%endif]
1210

1211
let pexp_apply (T f) (T fargs) =
1212
  let open Parsetree in
1✔
1213
  let helper ctx loc x k =
1214
    match x.pexp_desc with
1✔
1215
    | Pexp_apply (efun, eargs) -> k |> f ctx loc efun |> fargs ctx loc eargs
1✔
1216
    | _ -> fail loc "pexp_apply"
×
1217
  in
1218
  T helper
1219
;;
1220

1221
let tstr_zanuda_attr str =
1222
  tstr_attribute
316✔
1223
    (attribute
316✔
1224
       (string "zanuda")
316✔
1225
       (payload_stru (pstr_eval (pexp_constant (pconst_string str)) ^:: nil)))
316✔
1226
;;
1227

1228
let tstr_docattr on_str =
1229
  tstr_attribute
38✔
1230
    (attribute
38✔
1231
       drop
1232
       (payload_stru (pstr_eval (pexp_constant (pconst_string on_str)) ^:: nil)))
38✔
1233
;;
1234

1235
let tsig_docattr on_str =
1236
  tsig_attribute
3✔
1237
    (attribute
3✔
1238
       drop
1239
       (payload_stru (pstr_eval (pexp_constant (pconst_string on_str)) ^:: nil)))
3✔
1240
;;
1241

1242
type context = Ast_pattern0.context
1243

1244
let of_func f = T f
×
1245
let to_func (T f) = f
×
1246
let fail = fail
1247

1248
let%test_module "Fake tests, only to increase coverage" =
1249
  (module struct
1250
    [@@@coverage off]
1251

1252
    let noloc =
1253
      Warnings.
1254
        { loc_start = Lexing.dummy_pos; loc_end = Lexing.dummy_pos; loc_ghost = true }
1255
    ;;
1256

1257
    let%test _ =
1258
      match path_of_list [] with
1259
      | exception Failure _ -> true
1260
      | _ -> false
1261
    ;;
1262

1263
    let%test_unit _ =
1264
      let mk p ?(inv = false) what =
1265
        let on_error, rez =
1266
          if inv then Fun.const true, false else Fun.const false, true
1267
        in
1268
        parse p noloc ~on_error what rez
1269
      in
1270
      [%test_eq: Base.bool]
1271
        true
1272
        (mk
1273
           ~inv:true
1274
           (path_pident drop)
1275
           Path.(Pdot (Pident (Ident.create_local "List"), "map")));
1276
      [%test_eq: Base.bool]
1277
        true
1278
        (mk (path_pident drop) Path.(Pident (Ident.create_local "compare")));
1279
      [%test_eq: Base.bool] true (mk ~inv:true (labelled drop) Asttypes.Nolabel);
1280
      [%test_eq: Base.bool]
1281
        true
1282
        (mk
1283
           (econst drop)
1284
           { Typedtree.exp_desc = Texp_constant (Asttypes.Const_string ("", noloc, None))
1285
           ; exp_extra = []
1286
           ; exp_type = Predef.type_string
1287
           ; exp_loc = noloc
1288
           ; exp_env = Env.empty
1289
           ; exp_attributes = []
1290
           });
1291
      let _42 =
1292
        { Typedtree.exp_desc = Texp_constant (Asttypes.Const_int 42)
1293
        ; exp_extra = []
1294
        ; exp_type = Predef.type_int
1295
        ; exp_loc = noloc
1296
        ; exp_env = Env.empty
1297
        ; exp_attributes = []
1298
        }
1299
      in
1300
      [%test_eq: Base.bool] true (mk (econst drop) _42)
1301
    ;;
1302
  end)
1303
;;
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