Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
polymorphic_variant.ml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129open! Base open! Import open Common module Constructor = struct type t = { name : Name.t ; loc : Location.t ; fields : Tuple.t } let of_rtag lloc possibly_empty cts = let { txt = name; loc } = lloc in let name = Name.of_string name in let fields = match possibly_empty, cts with | true, [] -> Tuple.empty | false, [ _ ] -> Tuple.singleton | false, _ | true, _ :: _ -> unsupported ~loc "intersection type" in { name; loc; fields } ;; let wildcard_pattern { name; loc; fields } = let fields = Tuple.Polymorphic_variant.wildcard_pattern fields ~loc in ppat_variant ~loc (Name.to_constructor_string name) fields ;; let to_str { name; loc; fields } ~wildcard = Tuple.Polymorphic_variant.to_str fields ~loc ~name ~wildcard ;; end module Inherit = struct type t = { type_constructor : longident_loc ; loc : Location.t } let of_core_type ct = let loc = ct.ptyp_loc in match ct.ptyp_desc with | Ptyp_constr (type_constructor, []) -> { type_constructor; loc } | _ -> unsupported ~loc "non-simple type constructor in polymorphic variant" ;; let wildcard_pattern { type_constructor; loc } = ppat_type ~loc type_constructor let to_construct_expr { type_constructor; loc } = [%expr fun ([%p ppat_type ~loc type_constructor] as bt) -> bt] ;; let to_match_expr { type_constructor; loc } ~wildcard = [%expr function | [%p ppat_type ~loc type_constructor] as a -> First a | [%p wildcard] as bt -> Second bt] ;; let to_str ({ type_constructor; loc } as t) ~wildcard = let name = Longident.flatten_exn type_constructor.txt |> String.concat ~sep:"_" |> Name.of_string |> Name.to_lowercase_string in Polymorphize.binding ~loc ~name ~expr: [%expr Accessor.variant ~match_:[%e to_match_expr t ~wildcard] ~construct:[%e to_construct_expr t]] ;; end module Row = struct type t = | Constructor of Constructor.t | Inherit of Inherit.t let of_row_field rf = match rf.prf_desc with | Rtag (lloc, possibly_empty, cts) -> Constructor (Constructor.of_rtag lloc possibly_empty cts) | Rinherit ct -> Inherit (Inherit.of_core_type ct) ;; let wildcard_pattern = function | Constructor constructor -> Constructor.wildcard_pattern constructor | Inherit inherit_ -> Inherit.wildcard_pattern inherit_ ;; let to_str t ~wildcard = match t with | Constructor constructor -> Constructor.to_str constructor ~wildcard | Inherit inherit_ -> (match wildcard with | None -> Location.raise_errorf ~loc:inherit_.loc "Bug in ppx_accessor: unexpectedly lonely inherited polymorphic variant" | Some wildcard -> Inherit.to_str inherit_ ~wildcard) ;; end type t = Row.t list let of_row_fields = List.map ~f:Row.of_row_field let of_core_type_desc t ~loc = match t with | Ptyp_variant (rfs, Closed, None) -> of_row_fields rfs | Ptyp_variant _ -> unsupported ~loc "non-simple polymorphic variant" | _ -> unsupported ~loc "manifest type that is not a polymorphic variant" ;; let of_core_type ct = of_core_type_desc ct.ptyp_desc ~loc:ct.ptyp_loc let wildcard_patterns t ~loc = List.reduce (List.map t ~f:Row.wildcard_pattern) ~f:(ppat_or ~loc) ;; let to_strs t ~loc = Common.map_with_context t ~f:(fun constructor ~context:other_constructors -> let wildcard = wildcard_patterns other_constructors ~loc in Row.to_str constructor ~wildcard) ;;