@@ -250,7 +250,24 @@ let invoker ?(extra_types = []) uplift downlift body arguments =
250
250
in
251
251
let make_fun (label , pat ) (label' , typ ) expr =
252
252
assert (label' = label);
253
- Exp. fun_ label None (Pat. constraint_ pat typ) expr
253
+ match expr.pexp_desc with
254
+ | ((Pexp_function (params , c , b )) [@if ast_version >= 502 ]) ->
255
+ let params =
256
+ { pparam_desc = Pparam_val (nolabel, None , Pat. constraint_ pat typ)
257
+ ; pparam_loc = { expr.pexp_loc with loc_ghost = true }
258
+ }
259
+ :: params
260
+ in
261
+ let c, b =
262
+ match c, b with
263
+ | ( None
264
+ , Pfunction_body
265
+ { pexp_desc = Pexp_constraint (e, ty); pexp_attributes = [] ; _ } ) ->
266
+ Some (Pconstraint ty), Pfunction_body e
267
+ | _ -> c, b
268
+ in
269
+ { expr with pexp_desc = Pexp_function (params, c, b) }
270
+ | _ -> Exp. fun_ label None (Pat. constraint_ pat typ) expr
254
271
in
255
272
let invoker =
256
273
List. fold_right2
@@ -504,7 +521,7 @@ type field_desc =
504
521
string Asttypes .loc
505
522
* Asttypes .private_flag
506
523
* Asttypes .override_flag
507
- * Parsetree .expression
524
+ * ( Parsetree .expression * Parsetree .core_type option )
508
525
* Arg .t list
509
526
| Val of
510
527
string Asttypes .loc * Prop_kind .t * Asttypes .override_flag * Parsetree .expression
@@ -518,6 +535,29 @@ let filter_map f l =
518
535
in
519
536
List. rev l
520
537
538
+ let rec create_meth_ty exp =
539
+ match exp.pexp_desc with
540
+ | Pexp_fun (label , _ , _ , body ) -> label :: create_meth_ty body
541
+ | Pexp_function _ -> [ nolabel ]
542
+ | Pexp_newtype (_ , body ) -> create_meth_ty body
543
+ | _ -> []
544
+ [@@ if ast_version < 502 ]
545
+
546
+ let rec create_meth_ty exp =
547
+ match exp.pexp_desc with
548
+ | Pexp_function (params , _ , body ) -> (
549
+ List. filter_map params ~f: (function
550
+ | { pparam_desc = Pparam_newtype _ ; _ } -> None
551
+ | { pparam_desc = Pparam_val (label , _ , _arg ); _ } -> Some label)
552
+ @
553
+ match body with
554
+ | Pfunction_cases _ -> [ nolabel ]
555
+ | Pfunction_body e ->
556
+ (* TODO: should we recurse or not ? *)
557
+ create_meth_ty e)
558
+ | _ -> []
559
+ [@@ if ast_version > = 502 ]
560
+
521
561
let preprocess_literal_object mappper fields :
522
562
[ `Fields of field_desc list | `Error of _ ] =
523
563
let check_name id names =
@@ -581,22 +621,16 @@ let preprocess_literal_object mappper fields :
581
621
| Pcf_method (id , priv , Cfk_concrete (bang , body )) ->
582
622
let names = check_name id names in
583
623
let body, body_ty = drop_pexp_poly (mappper body) in
584
- let rec create_meth_ty exp =
585
- match exp.pexp_desc with
586
- | Pexp_fun (label , _ , _ , body ) -> label :: create_meth_ty body
587
- | Pexp_function _ -> [ nolabel ]
588
- | Pexp_newtype (_ , body ) -> create_meth_ty body
589
- | _ -> []
590
- in
591
624
let fun_ty =
592
625
List. map ~f: (fun label -> Arg. make ~label () ) (create_meth_ty body)
593
626
in
627
+
594
628
let body =
595
629
match body_ty with
596
- | None -> body
630
+ | None -> body, None
597
631
| Some { ptyp_desc = Ptyp_poly _ ; _ } ->
598
632
raise_errorf ~loc: exp.pcf_loc " Polymorphic method not supported."
599
- | Some ty -> Exp. constraint_ body ty
633
+ | Some ty -> body, Some ty
600
634
in
601
635
names, Meth (id, priv, bang, body, fun_ty) :: fields
602
636
| _ ->
@@ -649,8 +683,43 @@ let literal_object self_id (fields : field_desc list) =
649
683
in
650
684
let body = function
651
685
| Val (_ , _ , _ , body ) -> body
652
- | Meth (_ , _ , _ , body , _ ) ->
653
- Exp. fun_ ~loc: { body.pexp_loc with loc_ghost = true } Nolabel None self_id body
686
+ | Meth (_ , _ , _ , (body , ty ), _ ) -> (
687
+ match body.pexp_desc, ty with
688
+ | ((Pexp_function (params , c , b ), None) [@if ast_version >= 502 ]) ->
689
+ let params =
690
+ { pparam_desc = Pparam_val (nolabel, None , self_id)
691
+ ; pparam_loc = { body.pexp_loc with loc_ghost = true }
692
+ }
693
+ :: params
694
+ in
695
+ { body with pexp_desc = Pexp_function (params, c, b) }
696
+ | ((_ , Some ty ) [@if ast_version >= 502 ]) -> (
697
+ let e =
698
+ Exp. fun_
699
+ ~loc: { body.pexp_loc with loc_ghost = true }
700
+ Nolabel
701
+ None
702
+ self_id
703
+ body
704
+ in
705
+ match e.pexp_desc with
706
+ | Pexp_function (params , None, b ) ->
707
+ { e with pexp_desc = Pexp_function (params, Some (Pconstraint ty), b) }
708
+ | _ -> assert false )
709
+ | ((_ , Some ty ) [@if ast_version < 502 ]) ->
710
+ Exp. fun_
711
+ ~loc: { body.pexp_loc with loc_ghost = true }
712
+ Nolabel
713
+ None
714
+ self_id
715
+ (Exp. constraint_ body ty)
716
+ | _ , None ->
717
+ Exp. fun_
718
+ ~loc: { body.pexp_loc with loc_ghost = true }
719
+ Nolabel
720
+ None
721
+ self_id
722
+ body)
654
723
in
655
724
let extra_types =
656
725
List. concat
@@ -738,7 +807,23 @@ let literal_object self_id (fields : field_desc list) =
738
807
(self :: List. map fields ~f: (fun f -> (name f).txt))
739
808
~init: fake_object
740
809
~f: (fun name fun_ ->
741
- Exp. fun_ ~loc: gloc nolabel None (Pat. var ~loc: gloc (mknoloc name)) fun_))
810
+ match fun_.pexp_desc with
811
+ | ((Pexp_function (params , c , b )) [@if ast_version >= 502 ]) ->
812
+ let params =
813
+ { pparam_desc =
814
+ Pparam_val (nolabel, None , Pat. var ~loc: gloc (mknoloc name))
815
+ ; pparam_loc = { fun_.pexp_loc with loc_ghost = true }
816
+ }
817
+ :: params
818
+ in
819
+ { fun_ with pexp_desc = Pexp_function (params, c, b) }
820
+ | _ ->
821
+ Exp. fun_
822
+ ~loc: gloc
823
+ nolabel
824
+ None
825
+ (Pat. var ~loc: gloc (mknoloc name))
826
+ fun_))
742
827
with
743
828
pexp_attributes = [ merlin_hide ]
744
829
}
0 commit comments