Remove Aast.TCPartiallyAbstract
[hiphop-php.git] / hphp / hack / src / typing / write_symbol_info / symbol_build_json.ml
blob1774a2fc3c89b736794bfe0d8843ec785f1336e0
1 (*
2 * Copyright (c) Facebook, Inc. and its affiliates.
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the "hack" directory of this source tree.
7 * JSON builder functions. These all return JSON objects, which
8 * may be used to build up larger objects. The functions with suffix
9 * _nested include the key field because they are used for writing
10 * nested facts.
13 open Aast
14 open Ast_defs
15 open Hh_json
16 open Hh_prelude
17 open Symbol_json_util
19 let build_id_json fact_id =
20 JSON_Object [("id", JSON_Number (string_of_int fact_id))]
22 let build_file_json_nested filepath =
23 JSON_Object [("key", JSON_String filepath)]
25 let build_name_json_nested name =
26 (* Remove leading slash, if present, so names such as
27 Exception and \Exception are captured by the same fact *)
28 let basename = Utils.strip_ns name in
29 JSON_Object [("key", JSON_String basename)]
31 let rec build_namespaceqname_json_nested ns =
32 let fields =
33 match split_name ns with
34 | None -> [("name", build_name_json_nested ns)]
35 | Some (parent_ns, namespace) ->
37 ("name", build_name_json_nested namespace);
38 ("parent", build_namespaceqname_json_nested parent_ns);
41 JSON_Object [("key", JSON_Object fields)]
43 let build_qname_json_nested qname =
44 let fields =
45 match split_name qname with
46 (* Global namespace *)
47 | None -> [("name", build_name_json_nested qname)]
48 | Some (ns, name) ->
50 ("name", build_name_json_nested name);
51 ("namespace_", build_namespaceqname_json_nested ns);
54 JSON_Object [("key", JSON_Object fields)]
56 let build_method_decl_nested meth_name con_name con_type =
57 let cont_decl = JSON_Object [("name", build_qname_json_nested con_name)] in
58 let nested_cont_decl =
59 JSON_Object [(con_type, JSON_Object [("key", cont_decl)])]
61 let meth_decl =
62 JSON_Object
64 ("name", build_name_json_nested meth_name);
65 ("container", nested_cont_decl);
68 JSON_Object [("key", meth_decl)]
70 let build_type_json_nested type_name =
71 (* Remove namespace slash from type, if present *)
72 let ty = Utils.strip_ns type_name in
73 JSON_Object [("key", JSON_String ty)]
75 let build_signature_json_nested parameters return_type_name =
76 let fields =
77 let params = [("parameters", JSON_Array parameters)] in
78 match return_type_name with
79 | None -> params
80 | Some ty -> ("returns", build_type_json_nested ty) :: params
82 JSON_Object [("key", JSON_Object fields)]
84 let build_attributes_json_nested source_map attrs =
85 let attributes =
86 List.map attrs ~f:(fun attr ->
87 let (_, name) = attr.ua_name in
88 let params =
89 List.fold_right attr.ua_params ~init:[] ~f:(fun (_, pos, _) acc ->
90 let fp = Relative_path.to_absolute (Pos.filename pos) in
91 match SMap.find_opt fp source_map with
92 | Some st ->
93 JSON_String (strip_nested_quotes (source_at_span st pos)) :: acc
94 | None -> acc)
96 let fields =
98 ("name", build_name_json_nested name);
99 ("parameters", JSON_Array params);
102 JSON_Object [("key", JSON_Object fields)])
104 JSON_Array attributes
106 let build_bytespan_json pos =
107 let start = fst (Pos.info_raw pos) in
108 let length = Pos.length pos in
109 JSON_Object
111 ("start", JSON_Number (string_of_int start));
112 ("length", JSON_Number (string_of_int length));
115 let build_rel_bytespan_json offset len =
116 JSON_Object
118 ("offset", JSON_Number (string_of_int offset));
119 ("length", JSON_Number (string_of_int len));
122 let build_constraint_kind_json kind =
123 let num =
124 match kind with
125 | Constraint_as -> 0
126 | Constraint_eq -> 1
127 | Constraint_super -> 2
129 JSON_Number (string_of_int num)
131 let build_constraint_json ctx (kind, hint) =
132 let type_string = get_type_from_hint ctx hint in
133 JSON_Object
135 ("constraintKind", build_constraint_kind_json kind);
136 ("type", build_type_json_nested type_string);
139 let build_decl_target_json json = JSON_Object [("declaration", json)]
141 let build_occ_target_json json = JSON_Object [("occurrence", json)]
143 let build_file_lines_json filepath lineLengths endsInNewline hasUnicodeOrTabs =
144 let lengths =
145 List.map lineLengths ~f:(fun len -> JSON_Number (string_of_int len))
147 JSON_Object
149 ("file", build_file_json_nested filepath);
150 ("lengths", JSON_Array lengths);
151 ("endsInNewline", JSON_Bool endsInNewline);
152 ("hasUnicodeOrTabs", JSON_Bool hasUnicodeOrTabs);
155 let build_is_async_json fun_kind =
156 let is_async =
157 match fun_kind with
158 | FAsync -> true
159 | FAsyncGenerator -> true
160 | _ -> false
162 JSON_Bool is_async
164 let build_parameter_json
165 source_map param_name param_type_name def_val is_inout is_variadic attrs =
166 let fields =
168 ("name", build_name_json_nested param_name);
169 ("isInout", JSON_Bool is_inout);
170 ("isVariadic", JSON_Bool is_variadic);
171 ("attributes", build_attributes_json_nested source_map attrs);
174 let fields =
175 match param_type_name with
176 | None -> fields
177 | Some ty -> ("type", build_type_json_nested ty) :: fields
179 let fields =
180 match def_val with
181 | None -> fields
182 | Some expr ->
183 ("defaultValue", JSON_String (strip_nested_quotes expr)) :: fields
185 JSON_Object fields
187 let build_signature_json ctx source_map params vararg ret_ty =
188 let build_param p =
189 let ty =
190 match hint_of_type_hint p.param_type_hint with
191 | None -> None
192 | Some h -> Some (get_type_from_hint ctx h)
194 let is_inout =
195 match p.param_callconv with
196 | Pinout _ -> true
197 | Pnormal -> false
199 let def_value =
200 match p.param_expr with
201 | None -> None
202 | Some (_, expr_pos, _) ->
203 let fp = Relative_path.to_absolute (Pos.filename expr_pos) in
204 (match SMap.find_opt fp source_map with
205 | Some st -> Some (source_at_span st expr_pos)
206 | None -> None)
208 build_parameter_json
209 source_map
210 p.param_name
212 def_value
213 is_inout
214 p.param_is_variadic
215 p.param_user_attributes
217 let parameters = List.map params ~f:(fun param -> build_param param) in
218 let parameters =
219 match vararg with
220 | FVnonVariadic -> parameters
221 | FVellipsis _ ->
222 parameters
223 @ [build_parameter_json source_map "..." None None false true []]
224 | FVvariadicArg vararg -> parameters @ [build_param vararg]
226 let return_type_name =
227 match hint_of_type_hint ret_ty with
228 | None -> None
229 | Some h -> Some (get_type_from_hint ctx h)
231 build_signature_json_nested parameters return_type_name
233 let build_reify_kind_json kind =
234 let num =
235 match kind with
236 | Erased -> 0
237 | Reified -> 1
238 | SoftReified -> 2
240 JSON_Number (string_of_int num)
242 let build_type_const_kind_json kind =
243 let num =
244 match kind with
245 | TCAbstract _ -> 0
246 | TCConcrete _ -> 1
248 JSON_Number (string_of_int num)
250 let build_variance_json variance =
251 let num =
252 match variance with
253 | Contravariant -> 0
254 | Covariant -> 1
255 | Invariant -> 2
257 JSON_Number (string_of_int num)
259 let build_type_param_json ctx source_map tp =
260 let (_, name) = tp.tp_name in
261 let constraints = List.map tp.tp_constraints ~f:(build_constraint_json ctx) in
262 JSON_Object
264 ("name", build_name_json_nested name);
265 ("variance", build_variance_json tp.tp_variance);
266 ("reifyKind", build_reify_kind_json tp.tp_reified);
267 ("constraints", JSON_Array constraints);
268 ( "attributes",
269 build_attributes_json_nested source_map tp.tp_user_attributes );
272 let build_visibility_json (visibility : Aast.visibility) =
273 let num =
274 match visibility with
275 | Private -> 0
276 | Protected -> 1
277 | Public -> 2
278 | Internal -> 3
280 JSON_Number (string_of_int num)
282 let build_xrefs_json (xref_map : (Hh_json.json * Pos.t list) IMap.t) =
283 let xrefs =
284 IMap.fold
285 (fun _id (target_json, pos_list) acc ->
286 let sorted_pos = Caml.List.sort_uniq Pos.compare pos_list in
287 let (byte_spans, _) =
288 List.fold sorted_pos ~init:([], 0) ~f:(fun (spans, last_start) pos ->
289 let start = fst (Pos.info_raw pos) in
290 let length = Pos.length pos in
291 let span = build_rel_bytespan_json (start - last_start) length in
292 (spans @ [span], start))
294 let xref =
295 JSON_Object
296 [("target", target_json); ("ranges", JSON_Array byte_spans)]
298 xref :: acc)
299 xref_map
302 JSON_Array xrefs
304 (* These are functions for building JSON to reference some
305 existing fact. *)
307 let build_class_const_decl_json_ref fact_id =
308 JSON_Object [("classConst", build_id_json fact_id)]
310 let build_container_json_ref container_type fact_id =
311 JSON_Object [(container_type, build_id_json fact_id)]
313 let build_container_decl_json_ref container_type fact_id =
314 let container_json = build_container_json_ref container_type fact_id in
315 JSON_Object [("container", container_json)]
317 let build_enum_decl_json_ref fact_id =
318 build_container_decl_json_ref "enum_" fact_id
320 let build_enumerator_decl_json_ref fact_id =
321 JSON_Object [("enumerator", build_id_json fact_id)]
323 let build_func_decl_json_ref fact_id =
324 JSON_Object [("function_", build_id_json fact_id)]
326 let build_gconst_decl_json_ref fact_id =
327 JSON_Object [("globalConst", build_id_json fact_id)]
329 let build_method_decl_json_ref fact_id =
330 JSON_Object [("method", build_id_json fact_id)]
332 let build_property_decl_json_ref fact_id =
333 JSON_Object [("property_", build_id_json fact_id)]
335 let build_type_const_decl_json_ref fact_id =
336 JSON_Object [("typeConst", build_id_json fact_id)]
338 let build_typedef_decl_json_ref fact_id =
339 JSON_Object [("typedef_", build_id_json fact_id)]
341 let build_method_occ_json_ref fact_id =
342 JSON_Object [("method", build_id_json fact_id)]