|
| 1 | +open StdLabels |
| 2 | + |
| 3 | +module Type_tree = struct |
| 4 | + type node_data = |
| 5 | + | Arrow |
| 6 | + | Tuple |
| 7 | + | Object |
| 8 | + | Type_ref of { path : Path.t; ty : Types.type_expr } |
| 9 | + |
| 10 | + type t = { data : node_data; children : t list } |
| 11 | +end |
| 12 | + |
| 13 | +let rec flatten_arrow ret_ty = |
| 14 | + match Types.get_desc ret_ty with |
| 15 | + | Tarrow (_, ty1, ty2, _) -> ty1 :: flatten_arrow ty2 |
| 16 | + | _ -> [ ret_ty ] |
| 17 | + |
| 18 | +let rec create_type_tree ty : Type_tree.t option = |
| 19 | + match Types.get_desc ty with |
| 20 | + | Tarrow (_, ty1, ty2, _) -> |
| 21 | + let tys = ty1 :: flatten_arrow ty2 in |
| 22 | + let children = List.filter_map tys ~f:create_type_tree in |
| 23 | + Some { data = Arrow; children } |
| 24 | + | Ttuple tys | Tunboxed_tuple tys -> |
| 25 | + let children = |
| 26 | + List.filter_map tys ~f:(fun (_, ty) -> create_type_tree ty) |
| 27 | + in |
| 28 | + Some { data = Tuple; children } |
| 29 | + | Tconstr (path, arg_tys, abbrev_memo) -> |
| 30 | + let ty_without_args = |
| 31 | + Types.newty2 ~level:Ident.highest_scope (Tconstr (path, [], abbrev_memo)) |
| 32 | + in |
| 33 | + let children = List.filter_map arg_tys ~f:create_type_tree in |
| 34 | + Some { data = Type_ref { path; ty = ty_without_args }; children } |
| 35 | + | Tlink ty | Tpoly (ty, _) -> create_type_tree ty |
| 36 | + | Tobject (fields_type, _) -> |
| 37 | + let rec extract_field_types (ty : Types.type_expr) = |
| 38 | + match Types.get_desc ty with |
| 39 | + | Tfield (_, _, ty, rest) -> ty :: extract_field_types rest |
| 40 | + | _ -> [] |
| 41 | + in |
| 42 | + let field_types = List.rev (extract_field_types fields_type) in |
| 43 | + let children = List.filter_map field_types ~f:create_type_tree in |
| 44 | + Some { data = Object; children } |
| 45 | + | Tnil | Tvar _ | Tsubst _ | Tvariant _ | Tunivar _ | Tpackage _ | Tfield _ -> |
| 46 | + None |
0 commit comments