|
1 | 1 | open Flow_tree |
2 | 2 |
|
| 3 | +module SSet = Set.Make(String) |
| 4 | +module SMap = Map.Make(String) |
| 5 | + |
3 | 6 | type state = { |
4 | 7 | env: Env.t; |
5 | 8 | mutable used_types: string list; |
@@ -107,10 +110,63 @@ and p_any comment = p_named ~comment "any" |
107 | 110 |
|
108 | 111 | and p_named ?(tl=[]) ?comment name = T_name (name, tl, comment) |
109 | 112 |
|
| 113 | +let mk_type_name name used_names = |
| 114 | + let is_unique name = not (SSet.mem name used_names) in |
| 115 | + let rec loop i = |
| 116 | + let new_name = name ^ "$" ^ (string_of_int i) in |
| 117 | + if is_unique new_name then new_name else loop (i + 1) |
| 118 | + in |
| 119 | + if is_unique name then name else loop 0 |
| 120 | + |
| 121 | +let get_type_map types exports = |
| 122 | + let used_names = List.fold_left (fun names e -> |
| 123 | + print_endline ("add export " ^ e.decl_name); |
| 124 | + SSet.add e.decl_name names |
| 125 | + ) SSet.empty exports in |
| 126 | + let (_, type_map) = List.fold_left (fun (used_names, type_map) t -> |
| 127 | + print_endline ("add type " ^ t.decl_name); |
| 128 | + let name = mk_type_name t.decl_name used_names in |
| 129 | + let type_names = SSet.add name used_names in |
| 130 | + let type_map = SMap.add t.decl_name name type_map in |
| 131 | + (type_names, type_map) |
| 132 | + ) (used_names, SMap.empty) types in |
| 133 | + SMap.iter (fun k v -> print_endline (k ^ " -> " ^ v)) type_map; |
| 134 | + type_map |
| 135 | + |
| 136 | +let rename_types prog type_map = |
| 137 | + let get_name name = |
| 138 | + if SMap.mem name type_map then SMap.find name type_map else name |
| 139 | + in |
| 140 | + let rec rename t = |
| 141 | + match t with |
| 142 | + | T_name (name, tl, comment) -> |
| 143 | + let name = get_name name in |
| 144 | + let tl = List.map rename tl in |
| 145 | + T_name (name, tl, comment) |
| 146 | + | T_fun (args, ret) -> T_fun (List.map rename args, rename ret) |
| 147 | + | T_obj fields -> |
| 148 | + let map f = { |
| 149 | + field_name = f.field_name; |
| 150 | + field_type = rename f.field_type; |
| 151 | + } in |
| 152 | + T_obj (List.map map fields) |
| 153 | + | T_tuple tl -> T_tuple (List.map rename tl) |
| 154 | + in |
| 155 | + let prog_types = List.map (fun d -> |
| 156 | + {decl_name = get_name d.decl_name; decl_type = rename d.decl_type} |
| 157 | + ) prog.prog_types in |
| 158 | + let prog_exports = List.map (fun d -> |
| 159 | + {d with decl_type = rename d.decl_type} |
| 160 | + ) prog.prog_exports in |
| 161 | + {prog_types; prog_exports} |
| 162 | + |
110 | 163 | let print_signature env sigs = |
111 | 164 | let s = {env; used_types = []; types = []; exports = []} in |
112 | 165 | List.iter (p_sig s) sigs; |
113 | | - Flow_print.print { |
| 166 | + let prog = { |
114 | 167 | prog_types = List.rev s.types; |
115 | 168 | prog_exports = List.rev s.exports; |
116 | | - } |
| 169 | + } in |
| 170 | + let type_map = get_type_map s.types s.exports in |
| 171 | + let prog = rename_types prog type_map in |
| 172 | + Flow_print.print prog |
0 commit comments