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
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
=
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
=
45 match split_name qname
with
46 (* Global namespace *)
47 | None
-> [("name", build_name_json_nested qname
)]
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)])]
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
=
77 let params = [("parameters", JSON_Array parameters
)] in
78 match return_type_name
with
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
=
86 List.map attrs ~f
:(fun attr
->
87 let (_
, name
) = attr
.ua_name
in
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
93 JSON_String
(strip_nested_quotes
(source_at_span st pos
)) :: acc
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
111 ("start", JSON_Number
(string_of_int
start));
112 ("length", JSON_Number
(string_of_int
length));
115 let build_rel_bytespan_json offset len
=
118 ("offset", JSON_Number
(string_of_int offset
));
119 ("length", JSON_Number
(string_of_int len
));
122 let build_constraint_kind_json kind
=
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
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
=
145 List.map lineLengths ~f
:(fun len
-> JSON_Number
(string_of_int len
))
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
=
159 | FAsyncGenerator
-> true
164 let build_parameter_json
165 source_map param_name param_type_name def_val is_inout is_variadic attrs
=
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
);
175 match param_type_name
with
177 | Some
ty -> ("type", build_type_json_nested ty) :: fields
183 ("defaultValue", JSON_String
(strip_nested_quotes expr
)) :: fields
187 let build_signature_json ctx source_map
params vararg ret_ty
=
190 match hint_of_type_hint p
.param_type_hint
with
192 | Some h
-> Some
(get_type_from_hint ctx h
)
195 match p
.param_callconv
with
200 match p
.param_expr
with
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
)
215 p
.param_user_attributes
217 let parameters = List.map
params ~f
:(fun param
-> build_param param
) in
220 | FVnonVariadic
-> 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
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
=
240 JSON_Number
(string_of_int
num)
242 let build_type_const_kind_json kind
=
248 JSON_Number
(string_of_int
num)
250 let build_variance_json variance
=
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
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);
269 build_attributes_json_nested source_map tp
.tp_user_attributes
);
272 let build_visibility_json (visibility
: Aast.visibility
) =
274 match visibility
with
280 JSON_Number
(string_of_int
num)
282 let build_xrefs_json (xref_map
: (Hh_json.json
* Pos.t list
) IMap.t
) =
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))
296 [("target", target_json
); ("ranges", JSON_Array byte_spans
)]
304 (* These are functions for building JSON to reference some
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
)]