move string-related utils into String_utils
[hiphop-php.git] / hphp / hack / src / utils / errors.ml
blob1a5430b126e63e8e23ee8a98dccd2b7a2f441a39
1 (**
2 * Copyright (c) 2015, Facebook, Inc.
3 * All rights reserved.
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the "hack" directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
9 *)
11 open Core
12 open Utils
13 open String_utils
16 type error_code = int
17 (* We use `Pos.t message` on the server and convert to `Pos.absolute message`
18 * before sending it to the client *)
19 type 'a message = 'a * string
21 module Common = struct
23 let try_with_result f1 f2 error_list accumulate_errors =
24 let error_list_copy = !error_list in
25 let accumulate_errors_copy = !accumulate_errors in
26 error_list := [];
27 accumulate_errors := true;
28 let result = f1 () in
29 let errors = !error_list in
30 error_list := error_list_copy;
31 accumulate_errors := accumulate_errors_copy;
32 match List.rev errors with
33 | [] -> result
34 | l :: _ -> f2 result l
36 let do_ f error_list accumulate_errors applied_fixmes =
37 let error_list_copy = !error_list in
38 let accumulate_errors_copy = !accumulate_errors in
39 let applied_fixmes_copy = !applied_fixmes in
40 error_list := [];
41 applied_fixmes := [];
42 accumulate_errors := true;
43 let result = f () in
44 let out_errors = !error_list in
45 let out_applied_fixmes = !applied_fixmes in
46 error_list := error_list_copy;
47 applied_fixmes := applied_fixmes_copy;
48 accumulate_errors := accumulate_errors_copy;
49 (List.rev out_errors, out_applied_fixmes), result
51 (*****************************************************************************)
52 (* Error code printing. *)
53 (*****************************************************************************)
55 let error_kind error_code =
56 match error_code / 1000 with
57 | 1 -> "Parsing"
58 | 2 -> "Naming"
59 | 3 -> "NastCheck"
60 | 4 -> "Typing"
61 | 5 -> "Lint"
62 | _ -> "Other"
64 let error_code_to_string error_code =
65 let error_kind = error_kind error_code in
66 let error_number = Printf.sprintf "%04d" error_code in
67 error_kind^"["^error_number^"]"
69 end
71 (** The mode abstracts away the underlying errors type so errors can be
72 * stored either with backtraces (TracingErrors) or without
73 * (NonTracingErrors). *)
74 module type Errors_modes = sig
76 type 'a error_
77 type error = Pos.t error_
78 type applied_fixme = Pos.t * int
79 val applied_fixmes: applied_fixme list ref
81 val try_with_result: (unit -> 'a) -> ('a -> error -> 'a) -> 'a
82 val do_: (unit -> 'a) -> (error list * applied_fixme list) * 'a
84 val add_error: error -> unit
85 val make_error: error_code -> (Pos.t message) list -> error
87 val get_code: 'a error_ -> error_code
88 val get_pos: error -> Pos.t
89 val to_list: 'a error_ -> 'a message list
90 val to_absolute : error -> Pos.absolute error_
92 val to_string : Pos.absolute error_ -> string
94 val get_sorted_error_list: error list * applied_fixme list -> error list
96 end
98 (** Errors don't hace backtraces embedded. *)
99 module NonTracingErrors: Errors_modes = struct
100 type 'a error_ = error_code * 'a message list
101 type error = Pos.t error_
102 type applied_fixme = Pos.t * int
103 let applied_fixmes: applied_fixme list ref = ref []
105 let (error_list: error list ref) = ref []
106 let accumulate_errors = ref false
108 let add_error error =
109 if !accumulate_errors
110 then error_list := error :: !error_list
111 else
112 (* We have an error, but haven't handled it in any way *)
113 assert_false_log_backtrace ()
115 let try_with_result f1 f2 =
116 Common.try_with_result f1 f2 error_list accumulate_errors
118 let do_ f =
119 Common.do_ f error_list accumulate_errors applied_fixmes
121 and make_error code (x: (Pos.t * string) list) = ((code, x): error)
123 (*****************************************************************************)
124 (* Accessors. *)
125 (*****************************************************************************)
127 and get_code (error: 'a error_) = ((fst error): error_code)
128 let get_pos (error : error) = fst (List.hd_exn (snd error))
129 let to_list (error : 'a error_) = snd error
130 let to_absolute error =
131 let code, msg_l = (get_code error), (to_list error) in
132 let msg_l = List.map msg_l (fun (p, s) -> Pos.to_absolute p, s) in
133 code, msg_l
135 let to_string (error : Pos.absolute error_) : string =
136 let error_code, msgl = (get_code error), (to_list error) in
137 let buf = Buffer.create 50 in
138 (match msgl with
139 | [] -> assert false
140 | (pos1, msg1) :: rest_of_error ->
141 Buffer.add_string buf begin
142 let error_code = Common.error_code_to_string error_code in
143 Printf.sprintf "%s\n%s (%s)\n"
144 (Pos.string pos1) msg1 error_code
145 end;
146 List.iter rest_of_error begin fun (p, w) ->
147 let msg = Printf.sprintf "%s\n%s\n" (Pos.string p) w in
148 Buffer.add_string buf msg
151 Buffer.contents buf
153 let get_sorted_error_list (err,_) =
154 List.sort ~cmp:begin fun x y ->
155 Pos.compare (get_pos x) (get_pos y)
156 end err
160 (** Errors with backtraces embedded. They are revealed with to_string. *)
161 module TracingErrors: Errors_modes = struct
162 type 'a error_ = (Printexc.raw_backtrace * error_code * 'a message list)
163 type error = Pos.t error_
164 type applied_fixme = Pos.t * int
165 let applied_fixmes: applied_fixme list ref = ref []
167 let (error_list: error list ref) = ref []
168 let accumulate_errors = ref false
170 let add_error error =
171 if !accumulate_errors
172 then error_list := error :: !error_list
173 else
174 (* We have an error, but haven't handled it in any way *)
175 assert_false_log_backtrace ()
177 let try_with_result f1 f2 =
178 Common.try_with_result f1 f2 error_list accumulate_errors
180 let do_ f =
181 Common.do_ f error_list accumulate_errors applied_fixmes
183 let make_error code (x: (Pos.t * string) list) =
184 let bt = Printexc.get_callstack 25 in
185 ((bt, code, x): error)
187 let get_code ((_, c, _): 'a error_) = c
189 let get_pos ((_, _, msg_l): error) =
190 fst (List.hd_exn msg_l)
192 let get_bt ((bt, _, _): 'a error_) = bt
194 let to_list ((_, _, l): 'a error_) = l
196 let to_absolute (error: error) =
197 let bt, code, msg_l = (get_bt error), (get_code error), (to_list error) in
198 let msg_l = List.map msg_l (fun (p, s) -> Pos.to_absolute p, s) in
199 bt, code, msg_l
201 (** TODO: Much of this is copy-pasta. *)
202 let to_string (error : Pos.absolute error_) : string =
203 let bt, error_code, msgl = (get_bt error),
204 (get_code error), (to_list error) in
205 let buf = Buffer.create 50 in
206 (match msgl with
207 | [] -> assert false
208 | (pos1, msg1) :: rest_of_error ->
209 Buffer.add_string buf begin
210 let error_code = Common.error_code_to_string error_code in
211 Printf.sprintf "%s\n%s%s (%s)\n"
212 (Pos.string pos1) (Printexc.raw_backtrace_to_string bt)
213 msg1 error_code
214 end;
215 List.iter rest_of_error begin fun (p, w) ->
216 let msg = Printf.sprintf "%s\n%s\n" (Pos.string p) w in
217 Buffer.add_string buf msg
220 Buffer.contents buf
222 let get_sorted_error_list (err,_) =
223 List.sort ~cmp:begin fun x y ->
224 Pos.compare (get_pos x) (get_pos y)
225 end err
229 (** The Errors functor which produces the Errors module.
230 * Omitting gratuitous indentation. *)
231 module Errors_with_mode(M: Errors_modes) = struct
233 (*****************************************************************************)
234 (* Types *)
235 (*****************************************************************************)
237 type 'a error_ = 'a M.error_
238 type error = Pos.t error_
239 type applied_fixme = M.applied_fixme
240 type t = error list * applied_fixme list
242 (*****************************************************************************)
243 (* HH_FIXMEs hook *)
244 (*****************************************************************************)
246 let applied_fixmes = M.applied_fixmes
248 let (is_hh_fixme: (Pos.t -> error_code -> bool) ref) = ref (fun _ _ -> false)
250 (*****************************************************************************)
251 (* Errors accumulator. *)
252 (*****************************************************************************)
254 let add_applied_fixme code pos =
255 applied_fixmes := (pos, code) :: !applied_fixmes
257 let rec add_error = M.add_error
259 and add code pos msg =
260 if !is_hh_fixme pos code then add_applied_fixme code pos else
261 add_error (M.make_error code [pos, msg])
263 and add_list code pos_msg_l =
264 let pos = fst (List.hd_exn pos_msg_l) in
265 if !is_hh_fixme pos code then add_applied_fixme code pos else
266 add_error (make_error code pos_msg_l)
268 and merge (err',fixmes') (err,fixmes) =
269 (List.rev_append err' err, List.rev_append fixmes' fixmes)
271 and empty = ([], [])
272 and is_empty (err, fixmes) = err = []
274 and get_error_list (err, fixmes) = err
275 and get_applied_fixmes (err, fixmes) = fixmes
276 and from_error_list err = (err, [])
278 (*****************************************************************************)
279 (* Accessors. (All methods delegated to the parameterized module.) *)
280 (*****************************************************************************)
282 and get_code = M.get_code
283 and get_pos = M.get_pos
284 and to_list = M.to_list
286 and make_error = M.make_error
288 let get_sorted_error_list = M.get_sorted_error_list
289 let iter_error_list f err = List.iter ~f:f (get_sorted_error_list err)
291 (*****************************************************************************)
292 (* Error code printing. *)
293 (*****************************************************************************)
295 let error_code_to_string = Common.error_code_to_string
297 (*****************************************************************************)
298 (* Error codes.
299 * Each error has a unique number associated with it. The following modules
300 * define the error code associated with each kind of error.
301 * It is ok to extend the codes with new values, it is NOT OK to change the
302 * value of an existing error to a different error code!
303 * I added some comments to make that extra clear :-)
305 (*****************************************************************************)
307 module Parsing = struct
308 let fixme_format = 1001 (* DONT MODIFY!!!! *)
309 let parsing_error = 1002 (* DONT MODIFY!!!! *)
310 let unexpected_eof = 1003 (* DONT MODIFY!!!! *)
311 let unterminated_comment = 1004 (* DONT MODIFY!!!! *)
312 let unterminated_xhp_comment = 1005 (* DONT MODIFY!!!! *)
313 let call_time_pass_by_reference = 1006 (* DONT MODIFY!!!! *)
314 (* EXTEND HERE WITH NEW VALUES IF NEEDED *)
317 module Naming = struct
318 let add_a_typehint = 2001 (* DONT MODIFY!!!! *)
319 let typeparam_alok = 2002 (* DONT MODIFY!!!! *)
320 let assert_arity = 2003 (* DONT MODIFY!!!! *)
321 let primitive_invalid_alias = 2004 (* DONT MODIFY!!!! *)
322 (* DECPRECATED let cyclic_constraint = 2005 *)
323 let did_you_mean_naming = 2006 (* DONT MODIFY!!!! *)
324 let different_scope = 2007 (* DONT MODIFY!!!! *)
325 let disallowed_xhp_type = 2008 (* DONT MODIFY!!!! *)
326 (* DEPRECATED let double_instead_of_float = 2009 *)
327 (* DEPRECATED let dynamic_class = 2010 *)
328 let dynamic_method_call = 2011 (* DONT MODIFY!!!! *)
329 let error_name_already_bound = 2012 (* DONT MODIFY!!!! *)
330 let expected_collection = 2013 (* DONT MODIFY!!!! *)
331 let expected_variable = 2014 (* DONT MODIFY!!!! *)
332 let fd_name_already_bound = 2015 (* DONT MODIFY!!!! *)
333 let gen_array_rec_arity = 2016 (* DONT MODIFY!!!! *)
334 (* let gen_array_va_rec_arity = 2017 *)
335 let gena_arity = 2018 (* DONT MODIFY!!!! *)
336 let generic_class_var = 2019 (* DONT MODIFY!!!! *)
337 let genva_arity = 2020 (* DONT MODIFY!!!! *)
338 let illegal_CLASS = 2021 (* DONT MODIFY!!!! *)
339 let illegal_class_meth = 2022 (* DONT MODIFY!!!! *)
340 let illegal_constant = 2023 (* DONT MODIFY!!!! *)
341 let illegal_fun = 2024 (* DONT MODIFY!!!! *)
342 let illegal_inst_meth = 2025 (* DONT MODIFY!!!! *)
343 let illegal_meth_caller = 2026 (* DONT MODIFY!!!! *)
344 let illegal_meth_fun = 2027 (* DONT MODIFY!!!! *)
345 (* DEPRECATED integer_instead_of_int = 2028 *)
346 let invalid_req_extends = 2029 (* DONT MODIFY!!!! *)
347 let invalid_req_implements = 2030 (* DONT MODIFY!!!! *)
348 let local_const = 2031 (* DONT MODIFY!!!! *)
349 let lowercase_this = 2032 (* DONT MODIFY!!!! *)
350 let method_name_already_bound = 2033 (* DONT MODIFY!!!! *)
351 let missing_arrow = 2034 (* DONT MODIFY!!!! *)
352 let missing_typehint = 2035 (* DONT MODIFY!!!! *)
353 let name_already_bound = 2036 (* DONT MODIFY!!!! *)
354 let naming_too_few_arguments = 2037 (* DONT MODIFY!!!! *)
355 let naming_too_many_arguments = 2038 (* DONT MODIFY!!!! *)
356 let primitive_toplevel = 2039 (* DONT MODIFY!!!! *)
357 (* DEPRECATED let real_instead_of_float = 2040 *)
358 let shadowed_type_param = 2041 (* DONT MODIFY!!!! *)
359 let start_with_T = 2042 (* DONT MODIFY!!!! *)
360 let this_must_be_return = 2043 (* DONT MODIFY!!!! *)
361 let this_no_argument = 2044 (* DONT MODIFY!!!! *)
362 let this_hint_outside_class = 2045 (* DONT MODIFY!!!! *)
363 let this_reserved = 2046 (* DONT MODIFY!!!! *)
364 let tparam_with_tparam = 2047 (* DONT MODIFY!!!! *)
365 let typedef_constraint = 2048 (* DONT MODIFY!!!! *)
366 let unbound_name = 2049 (* DONT MODIFY!!!! *)
367 let undefined = 2050 (* DONT MODIFY!!!! *)
368 let unexpected_arrow = 2051 (* DONT MODIFY!!!! *)
369 let unexpected_typedef = 2052 (* DONT MODIFY!!!! *)
370 let using_internal_class = 2053 (* DONT MODIFY!!!! *)
371 let void_cast = 2054 (* DONT MODIFY!!!! *)
372 let object_cast = 2055 (* DONT MODIFY!!!! *)
373 let unset_cast = 2056 (* DONT MODIFY!!!! *)
374 (* DEPRECATED let nullsafe_property_access = 2057 *)
375 let illegal_TRAIT = 2058 (* DONT MODIFY!!!! *)
376 (* DEPRECATED let shape_typehint = 2059 *)
377 let dynamic_new_in_strict_mode = 2060 (* DONT MODIFY!!!! *)
378 let invalid_type_access_root = 2061 (* DONT MODIFY!!!! *)
379 let duplicate_user_attribute = 2062 (* DONT MODIFY!!!! *)
380 let return_only_typehint = 2063 (* DONT MODIFY!!!! *)
381 let unexpected_type_arguments = 2064 (* DONT MODIFY!!!! *)
382 let too_many_type_arguments = 2065 (* DONT MODIFY!!!! *)
383 let classname_param = 2066 (* DONT MODIFY!!!! *)
384 let invalid_instanceof = 2067 (* DONT MODIFY!!!! *)
385 let name_is_reserved = 2068 (* DONT MODIFY!!!! *)
386 let dollardollar_unused = 2069 (* DONT MODIFY!!!! *)
388 (* EXTEND HERE WITH NEW VALUES IF NEEDED *)
391 module NastCheck = struct
392 let abstract_body = 3001 (* DONT MODIFY!!!! *)
393 let abstract_with_body = 3002 (* DONT MODIFY!!!! *)
394 let await_in_sync_function = 3003 (* DONT MODIFY!!!! *)
395 let call_before_init = 3004 (* DONT MODIFY!!!! *)
396 let case_fallthrough = 3005 (* DONT MODIFY!!!! *)
397 let continue_in_switch = 3006 (* DONT MODIFY!!!! *)
398 let dangerous_method_name = 3007 (* DONT MODIFY!!!! *)
399 let default_fallthrough = 3008 (* DONT MODIFY!!!! *)
400 let interface_with_member_variable = 3009 (* DONT MODIFY!!!! *)
401 let interface_with_static_member_variable = 3010 (* DONT MODIFY!!!! *)
402 let magic = 3011 (* DONT MODIFY!!!! *)
403 let no_construct_parent = 3012 (* DONT MODIFY!!!! *)
404 let non_interface = 3013 (* DONT MODIFY!!!! *)
405 let not_abstract_without_body = 3014 (* DONT MODIFY!!!! *)
406 let not_initialized = 3015 (* DONT MODIFY!!!! *)
407 let not_public_interface = 3016 (* DONT MODIFY!!!! *)
408 let requires_non_class = 3017 (* DONT MODIFY!!!! *)
409 let return_in_finally = 3018 (* DONT MODIFY!!!! *)
410 let return_in_gen = 3019 (* DONT MODIFY!!!! *)
411 let toString_returns_string = 3020 (* DONT MODIFY!!!! *)
412 let toString_visibility = 3021 (* DONT MODIFY!!!! *)
413 let toplevel_break = 3022 (* DONT MODIFY!!!! *)
414 let toplevel_continue = 3023 (* DONT MODIFY!!!! *)
415 let uses_non_trait = 3024 (* DONT MODIFY!!!! *)
416 let illegal_function_name = 3025 (* DONT MODIFY!!!! *)
417 let not_abstract_without_typeconst = 3026 (* DONT MODIFY!!!! *)
418 let typeconst_depends_on_external_tparam = 3027 (* DONT MODIFY!!!! *)
419 let typeconst_assigned_tparam = 3028 (* DONT MODIFY!!!! *)
420 let abstract_with_typeconst = 3029 (* DONT MODIFY!!!! *)
421 let constructor_required = 3030 (* DONT MODIFY!!!! *)
422 let interface_with_partial_typeconst = 3031 (* DONT MODIFY!!!! *)
423 let multiple_xhp_category = 3032 (* DONT MODIFY!!!! *)
424 (* EXTEND HERE WITH NEW VALUES IF NEEDED *)
427 module Typing = struct
428 (* let abstract_class_final = 4001 (\* DONT MODIFY!!!! *\) *)
429 let uninstantiable_class = 4002 (* DONT MODIFY!!!! *)
430 let anonymous_recursive = 4003 (* DONT MODIFY!!!! *)
431 let anonymous_recursive_call = 4004 (* DONT MODIFY!!!! *)
432 let array_access = 4005 (* DONT MODIFY!!!! *)
433 let array_append = 4006 (* DONT MODIFY!!!! *)
434 let array_cast = 4007 (* DONT MODIFY!!!! *)
435 let array_get_arity = 4008 (* DONT MODIFY!!!! *)
436 let bad_call = 4009 (* DONT MODIFY!!!! *)
437 let class_arity = 4010 (* DONT MODIFY!!!! *)
438 let const_mutation = 4011 (* DONT MODIFY!!!! *)
439 let constructor_no_args = 4012 (* DONT MODIFY!!!! *)
440 let cyclic_class_def = 4013 (* DONT MODIFY!!!! *)
441 let cyclic_typedef = 4014 (* DONT MODIFY!!!! *)
442 let discarded_awaitable = 4015 (* DONT MODIFY!!!! *)
443 let isset_empty_in_strict = 4016 (* DONT MODIFY!!!! *)
444 (* DEPRECATED dynamic_yield_private = 4017 *)
445 let enum_constant_type_bad = 4018 (* DONT MODIFY!!!! *)
446 let enum_switch_nonexhaustive = 4019 (* DONT MODIFY!!!! *)
447 let enum_switch_not_const = 4020 (* DONT MODIFY!!!! *)
448 let enum_switch_redundant = 4021 (* DONT MODIFY!!!! *)
449 let enum_switch_redundant_default = 4022 (* DONT MODIFY!!!! *)
450 let enum_switch_wrong_class = 4023 (* DONT MODIFY!!!! *)
451 let enum_type_bad = 4024 (* DONT MODIFY!!!! *)
452 let enum_type_typedef_mixed = 4025 (* DONT MODIFY!!!! *)
453 let expected_class = 4026 (* DONT MODIFY!!!! *)
454 let expected_literal_string = 4027 (* DONT MODIFY!!!! *)
455 (* DEPRECATED expected_static_int = 4028 *)
456 let expected_tparam = 4029 (* DONT MODIFY!!!! *)
457 let expecting_return_type_hint = 4030 (* DONT MODIFY!!!! *)
458 let expecting_return_type_hint_suggest = 4031 (* DONT MODIFY!!!! *)
459 let expecting_type_hint = 4032 (* DONT MODIFY!!!! *)
460 let expecting_type_hint_suggest = 4033 (* DONT MODIFY!!!! *)
461 let extend_final = 4035 (* DONT MODIFY!!!! *)
462 let field_kinds = 4036 (* DONT MODIFY!!!! *)
463 (* DEPRECATED field_missing = 4037 *)
464 let format_string = 4038 (* DONT MODIFY!!!! *)
465 let fun_arity_mismatch = 4039 (* DONT MODIFY!!!! *)
466 let fun_too_few_args = 4040 (* DONT MODIFY!!!! *)
467 let fun_too_many_args = 4041 (* DONT MODIFY!!!! *)
468 let fun_unexpected_nonvariadic = 4042 (* DONT MODIFY!!!! *)
469 let fun_variadicity_hh_vs_php56 = 4043 (* DONT MODIFY!!!! *)
470 let gena_expects_array = 4044 (* DONT MODIFY!!!! *)
471 let generic_array_strict = 4045 (* DONT MODIFY!!!! *)
472 let generic_static = 4046 (* DONT MODIFY!!!! *)
473 let implement_abstract = 4047 (* DONT MODIFY!!!! *)
474 let interface_final = 4048 (* DONT MODIFY!!!! *)
475 let invalid_shape_field_const = 4049 (* DONT MODIFY!!!! *)
476 let invalid_shape_field_literal = 4050 (* DONT MODIFY!!!! *)
477 let invalid_shape_field_name = 4051 (* DONT MODIFY!!!! *)
478 let invalid_shape_field_type = 4052 (* DONT MODIFY!!!! *)
479 let member_not_found = 4053 (* DONT MODIFY!!!! *)
480 let member_not_implemented = 4054 (* DONT MODIFY!!!! *)
481 let missing_assign = 4055 (* DONT MODIFY!!!! *)
482 let missing_constructor = 4056 (* DONT MODIFY!!!! *)
483 let missing_field = 4057 (* DONT MODIFY!!!! *)
484 (* DEPRECATED negative_tuple_index = 4058 *)
485 let self_outside_class = 4059 (* DONT MODIFY!!!! *)
486 let new_static_inconsistent = 4060 (* DONT MODIFY!!!! *)
487 let static_outside_class = 4061 (* DONT MODIFY!!!! *)
488 let non_object_member = 4062 (* DONT MODIFY!!!! *)
489 let null_container = 4063 (* DONT MODIFY!!!! *)
490 let null_member = 4064 (* DONT MODIFY!!!! *)
491 (*let nullable_parameter = 4065 *)
492 let option_return_only_typehint = 4066 (* DONT MODIFY!!!! *)
493 let object_string = 4067 (* DONT MODIFY!!!! *)
494 let option_mixed = 4068 (* DONT MODIFY!!!! *)
495 let overflow = 4069 (* DONT MODIFY!!!! *)
496 let override_final = 4070 (* DONT MODIFY!!!! *)
497 let override_per_trait = 4071 (* DONT MODIFY!!!! *)
498 let pair_arity = 4072 (* DONT MODIFY!!!! *)
499 let abstract_call = 4073 (* DONT MODIFY!!!! *)
500 let parent_in_trait = 4074 (* DONT MODIFY!!!! *)
501 let parent_outside_class = 4075 (* DONT MODIFY!!!! *)
502 let parent_undefined = 4076 (* DONT MODIFY!!!! *)
503 let previous_default = 4077 (* DONT MODIFY!!!! *)
504 let private_class_meth = 4078 (* DONT MODIFY!!!! *)
505 let private_inst_meth = 4079 (* DONT MODIFY!!!! *)
506 let private_override = 4080 (* DONT MODIFY!!!! *)
507 let protected_class_meth = 4081 (* DONT MODIFY!!!! *)
508 let protected_inst_meth = 4082 (* DONT MODIFY!!!! *)
509 let read_before_write = 4083 (* DONT MODIFY!!!! *)
510 let return_in_void = 4084 (* DONT MODIFY!!!! *)
511 let shape_field_class_mismatch = 4085 (* DONT MODIFY!!!! *)
512 let shape_field_type_mismatch = 4086 (* DONT MODIFY!!!! *)
513 let should_be_override = 4087 (* DONT MODIFY!!!! *)
514 let sketchy_null_check = 4088 (* DONT MODIFY!!!! *)
515 let sketchy_null_check_primitive = 4089 (* DONT MODIFY!!!! *)
516 let smember_not_found = 4090 (* DONT MODIFY!!!! *)
517 let static_dynamic = 4091 (* DONT MODIFY!!!! *)
518 (* DEPRECATED let static_overflow = 4092 *)
519 let this_in_static = 4094 (* DONT MODIFY!!!! *)
520 let this_var_outside_class = 4095 (* DONT MODIFY!!!! *)
521 let trait_final = 4096 (* DONT MODIFY!!!! *)
522 let tuple_arity = 4097 (* DONT MODIFY!!!! *)
523 let tuple_arity_mismatch = 4098 (* DONT MODIFY!!!! *)
524 (* DEPRECATED tuple_index_too_large = 4099 *)
525 let tuple_syntax = 4100 (* DONT MODIFY!!!! *)
526 let type_arity_mismatch = 4101 (* DONT MODIFY!!!! *)
527 let type_param_arity = 4102 (* DONT MODIFY!!!! *)
528 let typing_too_few_args = 4104 (* DONT MODIFY!!!! *)
529 let typing_too_many_args = 4105 (* DONT MODIFY!!!! *)
530 let unbound_global = 4106 (* DONT MODIFY!!!! *)
531 let unbound_name_typing = 4107 (* DONT MODIFY!!!! *)
532 let undefined_field = 4108 (* DONT MODIFY!!!! *)
533 let undefined_parent = 4109 (* DONT MODIFY!!!! *)
534 let unify_error = 4110 (* DONT MODIFY!!!! *)
535 let unsatisfied_req = 4111 (* DONT MODIFY!!!! *)
536 let visibility = 4112 (* DONT MODIFY!!!! *)
537 let visibility_extends = 4113 (* DONT MODIFY!!!! *)
538 (* DEPRECATED void_parameter = 4114 *)
539 let wrong_extend_kind = 4115 (* DONT MODIFY!!!! *)
540 let generic_unify = 4116 (* DONT MODIFY!!!! *)
541 let nullsafe_not_needed = 4117 (* DONT MODIFY!!!! *)
542 let trivial_strict_eq = 4118 (* DONT MODIFY!!!! *)
543 let void_usage = 4119 (* DONT MODIFY!!!! *)
544 let declared_covariant = 4120 (* DONT MODIFY!!!! *)
545 let declared_contravariant = 4121 (* DONT MODIFY!!!! *)
546 (* DEPRECATED unset_in_strict = 4122 *)
547 let strict_members_not_known = 4123 (* DONT MODIFY!!!! *)
548 let generic_at_runtime = 4124 (* DONT MODIFY!!!! *)
549 (*let dynamic_class = 4125 *)
550 let attribute_too_many_arguments = 4126 (* DONT MODIFY!!!! *)
551 let attribute_param_type = 4127 (* DONT MODIFY!!!! *)
552 let deprecated_use = 4128 (* DONT MODIFY!!!! *)
553 let abstract_const_usage = 4129 (* DONT MODIFY!!!! *)
554 let cannot_declare_constant = 4130 (* DONT MODIFY!!!! *)
555 let cyclic_typeconst = 4131 (* DONT MODIFY!!!! *)
556 let nullsafe_property_write_context = 4132 (* DONT MODIFY!!!! *)
557 let noreturn_usage = 4133 (* DONT MODIFY!!!! *)
558 let this_lvalue = 4134 (* DONT MODIFY!!!! *)
559 let unset_nonidx_in_strict = 4135 (* DONT MODIFY!!!! *)
560 let invalid_shape_field_name_empty = 4136 (* DONT MODIFY!!!! *)
561 let invalid_shape_field_name_number = 4137 (* DONT MODIFY!!!! *)
562 let shape_fields_unknown = 4138 (* DONT MODIFY!!!! *)
563 let invalid_shape_remove_key = 4139 (* DONT MODIFY!!!! *)
564 let missing_optional_field = 4140 (* DONT MODIFY!!!! *)
565 let shape_field_unset = 4141 (* DONT MODIFY!!!! *)
566 let abstract_concrete_override = 4142 (* DONT MODIFY!!!! *)
567 let local_variable_modifed_and_used = 4143 (* DONT MODIFY!!!! *)
568 let local_variable_modifed_twice = 4144 (* DONT MODIFY!!!! *)
569 let assign_during_case = 4145 (* DONT MODIFY!!!! *)
570 let cyclic_enum_constraint = 4146 (* DONT MODIFY!!!! *)
571 let unpacking_disallowed = 4147 (* DONT MODIFY!!!! *)
572 let invalid_classname = 4148 (* DONT MODIFY!!!! *)
573 let invalid_memoized_param = 4149 (* DONT MODIFY!!!! *)
574 let illegal_type_structure = 4150 (* DONT MODIFY!!!! *)
575 let not_nullable_compare_null_trivial = 4151 (* DONT MODIFY!!!! *)
576 let class_property_only_static_literal = 4152 (* DONT MODIFY!!!! *)
577 let attribute_too_few_arguments = 4153 (* DONT MODIFY!!!! *)
578 let reference_expr = 4154 (* DONT MODIFY!!!! *)
579 let unification_cycle = 4155 (* DONT MODIFY!!!! *)
580 (* EXTEND HERE WITH NEW VALUES IF NEEDED *)
583 let internal_error pos msg =
584 add 0 pos ("Internal error: "^msg)
586 let unimplemented_feature pos msg =
587 add 0 pos ("Feature not implemented: " ^ msg)
589 (*****************************************************************************)
590 (* Parsing errors. *)
591 (*****************************************************************************)
593 let fixme_format pos =
594 add Parsing.fixme_format pos
595 "HH_FIXME wrong format, expected '/* HH_FIXME[ERROR_NUMBER] */'"
597 let unexpected_eof pos =
598 add Parsing.unexpected_eof pos "Unexpected end of file"
600 let unterminated_comment pos =
601 add Parsing.unterminated_comment pos "unterminated comment"
603 let unterminated_xhp_comment pos =
604 add Parsing.unterminated_xhp_comment pos "unterminated xhp comment"
606 let parsing_error (p, msg) =
607 add Parsing.parsing_error p msg
609 let call_time_pass_by_reference pos =
610 let msg = "Call-time pass-by-reference is not allowed" in
611 add Parsing.call_time_pass_by_reference pos msg
612 (*****************************************************************************)
613 (* Naming errors *)
614 (*****************************************************************************)
616 let typeparam_alok (pos, x) =
617 add Naming.typeparam_alok pos (
618 "You probably forgot to bind this type parameter right?\nAdd <"^x^
619 "> somewhere (after the function name definition, \
620 or after the class name)\nExamples: "^"function foo<T> or class A<T>")
622 let generic_class_var pos =
623 add Naming.generic_class_var pos
624 "A class variable cannot be generic"
626 let unexpected_arrow pos cname =
627 add Naming.unexpected_arrow pos (
628 "Keys may not be specified for "^cname^" initialization"
631 let missing_arrow pos cname =
632 add Naming.missing_arrow pos (
633 "Keys must be specified for "^cname^" initialization"
636 let disallowed_xhp_type pos name =
637 add Naming.disallowed_xhp_type pos (
638 name^" is not a valid type. Use :xhp or XHPChild."
641 let name_already_bound name pos1 pos2 =
642 let name = Utils.strip_ns name in
643 add_list Naming.name_already_bound [
644 pos1, "Name already bound: "^name;
645 pos2, "Previous definition is here"
648 let name_is_reserved name pos =
649 let name = Utils.strip_all_ns name in
650 add Naming.name_is_reserved pos (
651 name^" cannot be used as it is reserved."
654 let dollardollar_unused pos =
655 add Naming.dollardollar_unused pos ("This expression does not contain a "^
656 "usage of the special pipe variable. Did you forget to use the ($$) "^
657 "variable?")
659 let method_name_already_bound pos name =
660 add Naming.method_name_already_bound pos (
661 "Method name already bound: "^name
664 let error_name_already_bound name name_prev p p_prev =
665 let name = Utils.strip_ns name in
666 let name_prev = Utils.strip_ns name_prev in
667 let errs = [
668 p, "Name already bound: "^name;
669 p_prev, (if String.compare name name_prev == 0
670 then "Previous definition is here"
671 else "Previous definition "^name_prev^" differs only in capitalization ")
672 ] in
673 let hhi_msg =
674 "This appears to be defined in an hhi file included in your project "^
675 "root. The hhi files for the standard library are now a part of the "^
676 "typechecker and must be removed from your project. Typically, you can "^
677 "do this by deleting the \"hhi\" directory you copied into your "^
678 "project when first starting with Hack." in
679 let errs =
680 if (Relative_path.prefix (Pos.filename p)) = Relative_path.Hhi
681 then errs @ [p_prev, hhi_msg]
682 else if (Relative_path.prefix (Pos.filename p_prev)) = Relative_path.Hhi
683 then errs @ [p, hhi_msg]
684 else errs in
685 add_list Naming.error_name_already_bound errs
687 let unbound_name pos name kind =
688 let kind_str = match kind with
689 | `cls -> "an object type"
690 | `func -> "a global function"
691 | `const -> "a global constant"
693 add Naming.unbound_name pos
694 ("Unbound name: "^(strip_ns name)^" ("^kind_str^")")
696 let different_scope pos var_name pos' =
697 add_list Naming.different_scope [
698 pos, ("The variable "^ var_name ^" is defined");
699 pos', ("But in a different scope")
702 let undefined pos var_name =
703 add Naming.undefined pos ("Undefined variable: "^var_name)
705 let this_reserved pos =
706 add Naming.this_reserved pos
707 "The type parameter \"this\" is reserved"
709 let start_with_T pos =
710 add Naming.start_with_T pos
711 "Please make your type parameter start with the letter T (capital)"
713 let already_bound pos name =
714 add Naming.name_already_bound pos ("Argument already bound: "^name)
716 let unexpected_typedef pos def_pos =
717 add_list Naming.unexpected_typedef [
718 pos, "Unexpected typedef";
719 def_pos, "Definition is here";
722 let fd_name_already_bound pos =
723 add Naming.fd_name_already_bound pos
724 "Field name already bound"
726 let primitive_toplevel pos =
727 add Naming.primitive_toplevel pos (
728 "Primitive type annotations are always available and may no \
729 longer be referred to in the toplevel namespace."
732 let primitive_invalid_alias pos used valid =
733 add Naming.primitive_invalid_alias pos
734 ("Invalid Hack type. Using '"^used^"' in Hack is considered \
735 an error. Use '"^valid^"' instead, to keep the codebase \
736 consistent.")
738 let dynamic_new_in_strict_mode pos =
739 add Naming.dynamic_new_in_strict_mode pos
740 "Cannot use dynamic new in strict mode"
742 let invalid_type_access_root (pos, id) =
743 add Naming.invalid_type_access_root pos
744 (id^" must be an identifier for a class, \"self\", or \"this\"")
746 let duplicate_user_attribute (pos, name) existing_attr_pos =
747 add_list Naming.duplicate_user_attribute [
748 pos, "You cannot reuse the attribute "^name;
749 existing_attr_pos, name^" was already used here";
752 let unbound_attribute_name pos name =
753 let reason = if (string_starts_with name "__")
754 then "starts with __ but is not a standard attribute"
755 else "is not listed in .hhconfig"
756 in add Naming.unbound_name pos
757 ("Unrecognized user attribute: "^name^" "^reason)
759 let this_no_argument pos =
760 add Naming.this_no_argument pos "\"this\" expects no arguments"
762 let void_cast pos =
763 add Naming.void_cast pos "Cannot cast to void."
765 let unset_cast pos =
766 add Naming.unset_cast pos "Don't use (unset), just assign null!"
768 let object_cast pos x =
769 add Naming.object_cast pos ("Object casts are unsupported. "^
770 "Try 'if ($var instanceof "^x^")' or "^
771 "'invariant($var instanceof "^x^", ...)'.")
773 let this_hint_outside_class pos =
774 add Naming.this_hint_outside_class pos
775 "Cannot use \"this\" outside of a class"
777 let this_type_forbidden pos =
778 add Naming.this_must_be_return pos
779 "The type \"this\" cannot be used as a constraint on a class' generic, \
780 or as the type of a static member variable"
782 let lowercase_this pos type_ =
783 add Naming.lowercase_this pos (
784 "Invalid Hack type \""^type_^"\". Use \"this\" instead"
787 let classname_param pos =
788 add Naming.classname_param pos
789 ("Missing type parameter to classname; classname is entirely"
790 ^" meaningless without one")
792 let invalid_instanceof pos =
793 add Naming.invalid_instanceof pos
794 "This instanceof has an invalid right operand. Only class identifiers, \
795 local variables, accesses of objects / classes / arrays, and function / \
796 method calls are allowed."
798 let tparam_with_tparam pos x =
799 add Naming.tparam_with_tparam pos (
800 Printf.sprintf "%s is a type parameter. Type parameters cannot \
801 themselves take type parameters (e.g. %s<int> doesn't make sense)" x x
804 let shadowed_type_param p pos name =
805 add_list Naming.shadowed_type_param [
806 p, Printf.sprintf "You cannot re-bind the type parameter %s" name;
807 pos, Printf.sprintf "%s is already bound here" name
810 let missing_typehint pos =
811 add Naming.missing_typehint pos
812 "Please add a type hint"
814 let expected_variable pos =
815 add Naming.expected_variable pos
816 "Was expecting a variable name"
818 let naming_too_few_arguments pos =
819 add Naming.naming_too_few_arguments pos
820 "Too few arguments"
822 let naming_too_many_arguments pos =
823 add Naming.naming_too_many_arguments pos
824 "Too many arguments"
826 let expected_collection pos cn =
827 add Naming.expected_collection pos (
828 "Unexpected collection type " ^ (Utils.strip_ns cn)
831 let illegal_CLASS pos =
832 add Naming.illegal_CLASS pos
833 "Using __CLASS__ outside a class or trait"
835 let illegal_TRAIT pos =
836 add Naming.illegal_TRAIT pos
837 "Using __TRAIT__ outside a trait"
839 let dynamic_method_call pos =
840 add Naming.dynamic_method_call pos
841 "Dynamic method call"
843 let nullsafe_property_write_context pos =
844 add Typing.nullsafe_property_write_context pos
845 "?-> syntax not supported here, this function effectively does a write"
847 let illegal_fun pos =
848 let msg = "The argument to fun() must be a single-quoted, constant "^
849 "literal string representing a valid function name." in
850 add Naming.illegal_fun pos msg
852 let illegal_meth_fun pos =
853 let msg = "String argument to fun() contains ':';"^
854 " for static class methods, use"^
855 " class_meth(Cls::class, 'method_name'), not fun('Cls::method_name')" in
856 add Naming.illegal_meth_fun pos msg
858 let illegal_inst_meth pos =
859 let msg = "The argument to inst_meth() must be an expression and a "^
860 "constant literal string representing a valid method name." in
861 add Naming.illegal_inst_meth pos msg
863 let illegal_meth_caller pos =
864 let msg =
865 "The two arguments to meth_caller() must be:"
866 ^"\n - first: ClassOrInterface::class"
867 ^"\n - second: a single-quoted string literal containing the name"
868 ^" of a non-static method of that class" in
869 add Naming.illegal_meth_caller pos msg
871 let illegal_class_meth pos =
872 let msg =
873 "The two arguments to class_meth() must be:"
874 ^"\n - first: ValidClassname::class"
875 ^"\n - second: a single-quoted string literal containing the name"
876 ^" of a static method of that class" in
877 add Naming.illegal_class_meth pos msg
879 let assert_arity pos =
880 add Naming.assert_arity pos
881 "assert expects exactly one argument"
883 let gena_arity pos =
884 add Naming.gena_arity pos
885 "gena() expects exactly 1 argument"
887 let genva_arity pos =
888 add Naming.genva_arity pos
889 "genva() expects at least 1 argument"
891 let gen_array_rec_arity pos =
892 add Naming.gen_array_rec_arity pos
893 "gen_array_rec() expects exactly 1 argument"
895 let uninstantiable_class usage_pos decl_pos name reason_msgl =
896 let name = strip_ns name in
897 let msgl = [
898 usage_pos, (name^" is uninstantiable");
899 decl_pos, "Declaration is here"
900 ] in
901 let msgl = match reason_msgl with
902 | (reason_pos, reason_str) :: tail ->
903 (reason_pos, reason_str^" which must be instantiable") :: tail @ msgl
904 | _ -> msgl in
905 add_list Typing.uninstantiable_class msgl
907 let abstract_const_usage usage_pos decl_pos name =
908 let name = strip_ns name in
909 add_list Typing.abstract_const_usage [
910 usage_pos, ("Cannot reference abstract constant "^name^" directly");
911 decl_pos, "Declaration is here"
914 let typedef_constraint pos =
915 add Naming.typedef_constraint pos
916 "Constraints on typedefs are not supported"
918 let add_a_typehint pos =
919 add Naming.add_a_typehint pos
920 "Please add a type hint"
922 let local_const var_pos =
923 add Naming.local_const var_pos
924 "You cannot use a local variable in a constant definition"
926 let illegal_constant pos =
927 add Naming.illegal_constant pos
928 "Illegal constant value"
930 let invalid_req_implements pos =
931 add Naming.invalid_req_implements pos
932 "Only traits may use 'require implements'"
934 let invalid_req_extends pos =
935 add Naming.invalid_req_extends pos
936 "Only traits and interfaces may use 'require extends'"
938 let did_you_mean_naming pos name suggest_pos suggest_name =
939 add_list Naming.did_you_mean_naming [
940 pos, "Could not find "^(strip_ns name);
941 suggest_pos, "Did you mean "^(strip_ns suggest_name)^"?"
944 let using_internal_class pos name =
945 add Naming.using_internal_class pos (
946 name^" is an implementation internal class that cannot be used directly"
949 (*****************************************************************************)
950 (* Init check errors *)
951 (*****************************************************************************)
953 let no_construct_parent pos =
954 add NastCheck.no_construct_parent pos (
955 sl["You are extending a class that needs to be initialized\n";
956 "Make sure you call parent::__construct.\n"
960 let constructor_required (pos, name) prop_names =
961 let name = Utils.strip_ns name in
962 let props_str = SSet.fold (fun x acc -> x^" "^acc) prop_names "" in
963 add NastCheck.constructor_required pos
964 ("Lacking __construct, class "^name^" does not initialize its private member(s): "^props_str)
966 let not_initialized (pos, cname) prop_names =
967 let cname = Utils.strip_ns cname in
968 let props_str = SSet.fold (fun x acc -> x^" "^acc) prop_names "" in
969 let members, verb = if 1 == SSet.cardinal prop_names then "member", "is"
970 else "members", "are" in
971 let setters_str = SSet.fold (fun x acc -> "$this->"^x^" "^acc) prop_names "" in
972 add NastCheck.not_initialized pos (
974 "Class "; cname ; " does not initialize all of its members; ";
975 props_str; verb; " not always initialized.";
976 "\nMake sure you systematically set "; setters_str;
977 "when the method __construct is called.";
978 "\nAlternatively, you can define the "; members ;" as optional (?...)\n"
981 let call_before_init pos cv =
982 add NastCheck.call_before_init pos (
983 sl([
984 "Until the initialization of $this is over,";
985 " you can only call private methods\n";
986 "The initialization is not over because ";
988 if cv = "parent::__construct"
989 then ["you forgot to call parent::__construct"]
990 else ["$this->"; cv; " can still potentially be null"])
993 (*****************************************************************************)
994 (* Nast errors check *)
995 (*****************************************************************************)
997 let type_arity pos name nargs =
998 add Typing.type_arity_mismatch pos (
999 sl["The type ";(Utils.strip_ns name);
1000 " expects ";nargs;" type parameter(s)"]
1003 let abstract_with_body (p, _) =
1004 add NastCheck.abstract_with_body p
1005 "This method is declared as abstract, but has a body"
1007 let not_abstract_without_body (p, _) =
1008 add NastCheck.not_abstract_without_body p
1009 "This method is not declared as abstract, it must have a body"
1011 let not_abstract_without_typeconst (p, _) =
1012 add NastCheck.not_abstract_without_typeconst p
1013 ("This type constant is not declared as abstract, it must have"^
1014 " an assigned type")
1016 let abstract_with_typeconst (p, _) =
1017 add NastCheck.abstract_with_typeconst p
1018 ("This type constant is declared as abstract, it cannot be assigned a type")
1020 let typeconst_depends_on_external_tparam pos ext_pos ext_name =
1021 add_list NastCheck.typeconst_depends_on_external_tparam [
1022 pos, ("A type constant can only use type parameters declared in its own"^
1023 " type parameter list");
1024 ext_pos, (ext_name ^ " was declared as a type parameter here");
1027 let typeconst_assigned_tparam pos tp_name =
1028 add NastCheck.typeconst_assigned_tparam pos
1029 (tp_name ^" is a type parameter. It cannot be assigned to a type constant")
1031 let interface_with_partial_typeconst tconst_pos =
1032 add NastCheck.interface_with_partial_typeconst tconst_pos
1033 "An interface cannot contain a partially abstract type constant"
1035 let multiple_xhp_category pos =
1036 add NastCheck.multiple_xhp_category pos
1037 "XHP classes can only contain one category declaration"
1039 let return_in_gen p =
1040 add NastCheck.return_in_gen p
1041 ("You cannot return a value in a generator (a generator"^
1042 " is a function that uses yield)")
1044 let return_in_finally p =
1045 add NastCheck.return_in_finally p
1046 ("Don't use return in a finally block;"^
1047 " there's nothing to receive the return value")
1049 let toplevel_break p =
1050 add NastCheck.toplevel_break p
1051 "break can only be used inside loops or switch statements"
1053 let toplevel_continue p =
1054 add NastCheck.toplevel_continue p
1055 "continue can only be used inside loops"
1057 let continue_in_switch p =
1058 add NastCheck.continue_in_switch p
1059 ("In PHP, 'continue;' inside a switch \
1060 statement is equivalent to 'break;'."^
1061 " Hack does not support this; use 'break' if that is what you meant.")
1063 let await_in_sync_function p =
1064 add NastCheck.await_in_sync_function p
1065 "await can only be used inside async functions"
1067 let magic (p, s) =
1068 add NastCheck.magic p
1069 ("Don't call "^s^" it's one of these magic things we want to avoid")
1071 let non_interface (p : Pos.t) (c2: string) (verb: string): 'a =
1072 add NastCheck.non_interface p
1073 ("Cannot " ^ verb ^ " " ^ (strip_ns c2) ^ " - it is not an interface")
1075 let toString_returns_string pos =
1076 add NastCheck.toString_returns_string pos "__toString should return a string"
1078 let toString_visibility pos =
1079 add NastCheck.toString_visibility pos
1080 "__toString must have public visibility and cannot be static"
1082 let uses_non_trait (p: Pos.t) (n: string) (t: string) =
1083 add NastCheck.uses_non_trait p
1084 ((Utils.strip_ns n) ^ " is not a trait. It is " ^ t ^ ".")
1086 let requires_non_class (p: Pos.t) (n: string) (t: string) =
1087 add NastCheck.requires_non_class p
1088 ((Utils.strip_ns n) ^ " is not a class. It is " ^ t ^ ".")
1090 let abstract_body pos =
1091 add NastCheck.abstract_body pos "This method shouldn't have a body"
1093 let not_public_interface pos =
1094 add NastCheck.not_public_interface pos
1095 "Access type for interface method must be public"
1097 let interface_with_member_variable pos =
1098 add NastCheck.interface_with_member_variable pos
1099 "Interfaces cannot have member variables"
1101 let interface_with_static_member_variable pos =
1102 add NastCheck.interface_with_static_member_variable pos
1103 "Interfaces cannot have static variables"
1105 let illegal_function_name pos mname =
1106 add NastCheck.illegal_function_name pos
1107 ("Illegal function name: " ^ strip_ns mname)
1109 let dangerous_method_name pos =
1110 add NastCheck.dangerous_method_name pos (
1111 "This is a dangerous method name, "^
1112 "if you want to define a constructor, use "^
1113 "__construct"
1116 (*****************************************************************************)
1117 (* Nast terminality *)
1118 (*****************************************************************************)
1120 let case_fallthrough pos1 pos2 =
1121 add_list NastCheck.case_fallthrough [
1122 pos1, ("This switch has a case that implicitly falls through and is "^
1123 "not annotated with // FALLTHROUGH");
1124 pos2, "This case implicitly falls through"
1127 let default_fallthrough pos =
1128 add NastCheck.default_fallthrough pos
1129 ("This switch has a default case that implicitly falls "^
1130 "through and is not annotated with // FALLTHROUGH")
1132 (*****************************************************************************)
1133 (* Typing errors *)
1134 (*****************************************************************************)
1136 let visibility_extends vis pos parent_pos parent_vis =
1137 let msg1 = pos, "This member visibility is: " ^ vis in
1138 let msg2 = parent_pos, parent_vis ^ " was expected" in
1139 add_list Typing.visibility_extends [msg1; msg2]
1141 let member_not_implemented member_name parent_pos pos defn_pos =
1142 let msg1 = pos, "This object doesn't implement the method "^member_name in
1143 let msg2 = parent_pos, "Which is required by this interface" in
1144 let msg3 = defn_pos, "As defined here" in
1145 add_list Typing.member_not_implemented [msg1; msg2; msg3]
1147 let bad_decl_override parent_pos parent_name pos name (error: error) =
1148 let msg1 = pos, ("This object is of type "^(strip_ns name)) in
1149 let msg2 = parent_pos,
1150 ("It is incompatible with this object of type "^(strip_ns parent_name)^
1151 "\nbecause some declarations are incompatible."^
1152 "\nRead the following to see why:"
1153 ) in
1154 (* This is a cascading error message *)
1155 let code, msgl = (get_code error), (to_list error) in
1156 add_list code (msg1 :: msg2 :: msgl)
1158 let bad_enum_decl pos (error: error) =
1159 let msg = pos,
1160 "This enum declaration is invalid.\n\
1161 Read the following to see why:"
1163 (* This is a cascading error message *)
1164 let code, msgl = (get_code error), (to_list error) in
1165 add_list code (msg :: msgl)
1167 let missing_constructor pos =
1168 add Typing.missing_constructor pos
1169 "The constructor is not implemented"
1171 let typedef_trail_entry pos =
1172 pos, "Typedef definition comes from here"
1174 let add_with_trail code errs trail =
1175 add_list code (errs @ List.map trail typedef_trail_entry)
1177 let enum_constant_type_bad pos ty_pos ty trail =
1178 add_with_trail Typing.enum_constant_type_bad
1179 [pos, "Enum constants must be an int or string";
1180 ty_pos, "Not " ^ ty]
1181 trail
1183 let enum_type_bad pos ty trail =
1184 add_with_trail Typing.enum_type_bad
1185 [pos, "Enums must be int or string, not " ^ ty]
1186 trail
1188 let enum_type_typedef_mixed pos =
1189 add Typing.enum_type_typedef_mixed pos
1190 "Can't use typedef that resolves to mixed in enum"
1192 let enum_switch_redundant const first_pos second_pos =
1193 add_list Typing.enum_switch_redundant [
1194 second_pos, "Redundant case statement";
1195 first_pos, const ^ " already handled here"
1198 let enum_switch_nonexhaustive pos missing enum_pos =
1199 add_list Typing.enum_switch_nonexhaustive [
1200 pos, "Switch statement nonexhaustive; the following cases are missing: " ^
1201 String.concat ", " missing;
1202 enum_pos, "Enum declared here"
1205 let enum_switch_redundant_default pos enum_pos =
1206 add_list Typing.enum_switch_redundant_default [
1207 pos, "All cases already covered; a redundant default case prevents "^
1208 "detecting future errors";
1209 enum_pos, "Enum declared here"
1212 let enum_switch_not_const pos =
1213 add Typing.enum_switch_not_const pos
1214 "Case in switch on enum is not an enum constant"
1216 let enum_switch_wrong_class pos expected got =
1217 add Typing.enum_switch_wrong_class pos
1218 ("Switching on enum " ^ expected ^ " but using constant from " ^ got)
1220 let invalid_shape_field_name p =
1221 add Typing.invalid_shape_field_name p
1222 "Was expecting a constant string or class constant (for shape access)"
1224 let invalid_shape_field_name_empty p =
1225 add Typing.invalid_shape_field_name_empty p
1226 "A shape field name cannot be an empty string"
1228 let invalid_shape_field_name_number p =
1229 add Typing.invalid_shape_field_name_number p
1230 "A shape field name cannot start with numbers"
1232 let invalid_shape_field_type pos ty_pos ty trail =
1233 add_with_trail Typing.invalid_shape_field_type
1234 [pos, "A shape field name must be an int or string";
1235 ty_pos, "Not " ^ ty]
1236 trail
1238 let invalid_shape_field_literal key_pos witness_pos =
1239 add_list Typing.invalid_shape_field_literal
1240 [key_pos, "Shape uses literal string as field name";
1241 witness_pos, "But expected a class constant"]
1243 let invalid_shape_field_const key_pos witness_pos =
1244 add_list Typing.invalid_shape_field_const
1245 [key_pos, "Shape uses class constant as field name";
1246 witness_pos, "But expected a literal string"]
1248 let shape_field_class_mismatch key_pos witness_pos key_class witness_class =
1249 add_list Typing.shape_field_class_mismatch
1250 [key_pos, "Shape field name is class constant from " ^ key_class;
1251 witness_pos, "But expected constant from " ^ witness_class]
1253 let shape_field_type_mismatch key_pos witness_pos key_ty witness_ty =
1254 add_list Typing.shape_field_type_mismatch
1255 [key_pos, "Shape field name is " ^ key_ty ^ " class constant";
1256 witness_pos, "But expected " ^ witness_ty]
1258 let missing_field pos1 pos2 name =
1259 add_list Typing.missing_field (
1260 (pos1, "The field '"^name^"' is missing")::
1261 [pos2, "The field '"^name^"' is defined"])
1263 let missing_optional_field pos1 pos2 name =
1264 add_list Typing.missing_optional_field
1265 (* We have the position of shape type that is marked as optional -
1266 * explain why we can't omit it despite this.*)
1267 (if pos2 <> Pos.none then (
1268 (pos1, "The field '"^name^"' may be set to an unknown type. " ^
1269 "Explicitly null out the field, or remove it " ^
1270 "(with Shapes::removeKey(...))")::
1271 [pos2, "The field '"^name^"' is defined as optional"])
1272 else
1273 [pos1, "The field '"^name^"' is missing"])
1275 let shape_fields_unknown pos1 pos2 =
1276 add_list Typing.shape_fields_unknown
1277 [pos1, "This is a shape type coming from a type annotation. Because of " ^
1278 "structural subtyping it might have some other fields besides " ^
1279 "those listed in its declaration.";
1280 pos2, "It is incompatible with a shape created using \"shape\" "^
1281 "constructor, which has all the fields known"]
1283 let shape_field_unset pos1 pos2 name =
1284 add_list Typing.shape_field_unset (
1285 [(pos1, "The field '"^name^"' was unset here");
1286 (pos2, "The field '"^name^"' might be present in this shape because of " ^
1287 "structural subtyping")]
1290 let invalid_shape_remove_key p =
1291 add Typing.invalid_shape_remove_key p
1292 "You can only unset fields of local variables"
1294 let unification_cycle pos ty =
1295 add_list Typing.unification_cycle
1296 [pos, "Type circularity: in order to type-check this expression it " ^
1297 "is necessary for a type [rec] to be equal to type " ^ ty]
1300 let explain_constraint p_inst pos name (error : error) =
1301 let inst_msg = "Some type constraint(s) here are violated" in
1302 let code, msgl = (get_code error), (to_list error) in
1303 (* There may be multiple constraints instantiated at one spot; avoid
1304 * duplicating the instantiation message *)
1305 let msgl = match msgl with
1306 | (p, x) :: rest when x = inst_msg && p = p_inst -> rest
1307 | _ -> msgl in
1308 let name = Utils.strip_ns name in
1309 add_list code begin
1310 [p_inst, inst_msg;
1311 pos, "'"^name^"' is a constrained type"] @ msgl
1314 let explain_type_constant reason_msgl (error: error) =
1315 let code, msgl = (get_code error), (to_list error) in
1316 add_list code (msgl @ reason_msgl)
1318 let overflow p =
1319 add Typing.overflow p "Value is too large"
1321 let format_string pos snippet s class_pos fname class_suggest =
1322 add_list Typing.format_string [
1323 (pos, "I don't understand the format string " ^ snippet ^ " in " ^ s);
1324 (class_pos,
1325 "You can add a new format specifier by adding "
1326 ^fname^"() to "^class_suggest)]
1328 let expected_literal_string pos =
1329 add Typing.expected_literal_string pos
1330 "This argument must be a literal string"
1332 let generic_array_strict p =
1333 add Typing.generic_array_strict p
1334 "You cannot have an array without generics in strict mode"
1336 let strict_members_not_known p name =
1337 let name = Utils.strip_ns name in
1338 add Typing.strict_members_not_known p
1339 (name^" has a non-<?hh grandparent; this is not allowed in strict mode"
1340 ^" because that parent may define methods of unknowable name and type")
1342 let option_return_only_typehint p kind =
1343 let (typehint, reason) = match kind with
1344 | `void -> ("?void", "only return implicitly")
1345 | `noreturn -> ("?noreturn", "never return")
1347 add Typing.option_return_only_typehint p
1348 (typehint^" is a nonsensical typehint; a function cannot both "^reason
1349 ^" and return null.")
1351 let tuple_syntax p =
1352 add Typing.tuple_syntax p
1353 ("Did you want a tuple? Try (X,Y), not tuple<X,Y>")
1355 let class_arity usage_pos class_pos class_name arity =
1356 add_list Typing.class_arity
1357 [usage_pos, ("The class "^(Utils.strip_ns class_name)^" expects "^
1358 soi arity^" arguments");
1359 class_pos, "Definition is here"]
1361 let expecting_type_hint p =
1362 add Typing.expecting_type_hint p "Was expecting a type hint"
1364 let expecting_type_hint_suggest p ty =
1365 add Typing.expecting_type_hint_suggest p
1366 ("Was expecting a type hint (what about: "^ty^")")
1368 let expecting_return_type_hint p =
1369 add Typing.expecting_return_type_hint p
1370 "Was expecting a return type hint"
1372 let expecting_return_type_hint_suggest p ty =
1373 add Typing.expecting_return_type_hint_suggest p
1374 ("Was expecting a return type hint (what about: ': "^ty^"')")
1376 let field_kinds pos1 pos2 =
1377 add_list Typing.field_kinds
1378 [pos1, "You cannot use this kind of field (value)";
1379 pos2, "Mixed with this kind of field (key => value)"]
1381 let unbound_name_typing pos name =
1382 add Typing.unbound_name_typing pos
1383 ("Unbound name (typing): "^(strip_ns name))
1385 let previous_default p =
1386 add Typing.previous_default p
1387 ("A previous parameter has a default value.\n"^
1388 "Remove all the default values for the preceding parameters,\n"^
1389 "or add a default value to this one.")
1391 let return_only_typehint p kind =
1392 let msg = match kind with
1393 | `void -> "void"
1394 | `noreturn -> "noreturn" in
1395 add Naming.return_only_typehint p
1396 ("The "^msg^" typehint can only be used to describe a function return type")
1398 let unexpected_type_arguments p =
1399 add Naming.unexpected_type_arguments p
1400 ("Type arguments are not expected for this type")
1402 let too_many_type_arguments p =
1403 add Naming.too_many_type_arguments p
1404 ("Too many type arguments for this type")
1406 let return_in_void pos1 pos2 =
1407 add_list Typing.return_in_void [
1408 pos1,
1409 "You cannot return a value";
1410 pos2,
1411 "This is a void function"
1414 let this_in_static p =
1415 add Typing.this_in_static p "Don't use $this in a static method"
1417 let this_var_outside_class p =
1418 add Typing.this_var_outside_class p "Can't use $this outside of a class"
1420 let unbound_global cst_pos =
1421 add Typing.unbound_global cst_pos "Unbound global constant (Typing)"
1423 let private_inst_meth method_pos p =
1424 add_list Typing.private_inst_meth [
1425 method_pos, "This is a private method";
1426 p, "you cannot use it with inst_meth \
1427 (whether you are in the same class or not)."
1430 let protected_inst_meth method_pos p =
1431 add_list Typing.protected_inst_meth [
1432 method_pos, "This is a protected method";
1433 p, "you cannot use it with inst_meth \
1434 (whether you are in the same class hierarchy or not)."
1437 let private_class_meth pos1 pos2 =
1438 add_list Typing.private_class_meth [
1439 pos1, "This is a private method";
1440 pos2, "you cannot use it with class_meth \
1441 (whether you are in the same class or not)."
1444 let protected_class_meth pos1 pos2 =
1445 add_list Typing.protected_class_meth [
1446 pos1, "This is a protected method";
1447 pos2, "you cannot use it with class_meth \
1448 (whether you are in the same class hierarchy or not)."
1451 let array_cast pos =
1452 add Typing.array_cast pos
1453 "(array) cast forbidden in strict mode; arrays with unspecified \
1454 key and value types are not allowed"
1456 let anonymous_recursive pos =
1457 add Typing.anonymous_recursive pos
1458 "Anonymous functions cannot be recursive"
1460 let static_outside_class pos =
1461 add Typing.static_outside_class pos
1462 "'static' is undefined outside of a class"
1464 let self_outside_class pos =
1465 add Typing.self_outside_class pos
1466 "'self' is undefined outside of a class"
1468 let new_inconsistent_construct new_pos (cpos, cname) kind =
1469 let name = Utils.strip_ns cname in
1470 let preamble = match kind with
1471 | `static -> "Can't use new static() for "^name
1472 | `classname -> "Can't use new on classname<"^name^">"
1474 add_list Typing.new_static_inconsistent [
1475 new_pos, preamble^"; __construct arguments are not \
1476 guaranteed to be consistent in child classes";
1477 cpos, ("This declaration neither defines an abstract/final __construct"
1478 ^" nor uses <<__ConsistentConstruct>> attribute")]
1480 let pair_arity pos =
1481 add Typing.pair_arity pos "A pair has exactly 2 elements"
1483 let tuple_arity pos2 size2 pos1 size1 =
1484 add_list Typing.tuple_arity [
1485 pos2, "This tuple has "^ string_of_int size2^" elements";
1486 pos1, string_of_int size1 ^ " were expected"]
1488 let undefined_parent pos =
1489 add Typing.undefined_parent pos
1490 "The parent class is undefined"
1492 let parent_outside_class pos =
1493 add Typing.parent_outside_class pos
1494 "'parent' is undefined outside of a class"
1496 let parent_abstract_call meth_name call_pos decl_pos =
1497 add_list Typing.abstract_call [
1498 call_pos, ("Cannot call parent::"^meth_name^"(); it is abstract");
1499 decl_pos, "Declaration is here"
1502 let self_abstract_call meth_name call_pos decl_pos =
1503 add_list Typing.abstract_call [
1504 call_pos, ("Cannot call self::"^meth_name^"(); it is abstract. Did you mean static::"^meth_name^"()?");
1505 decl_pos, "Declaration is here"
1508 let classname_abstract_call cname meth_name call_pos decl_pos =
1509 let cname = Utils.strip_ns cname in
1510 add_list Typing.abstract_call [
1511 call_pos, ("Cannot call "^cname^"::"^meth_name^"(); it is abstract");
1512 decl_pos, "Declaration is here"
1515 let isset_empty_in_strict pos name =
1516 let name = Utils.strip_ns name in
1517 add Typing.isset_empty_in_strict pos
1518 (name^" cannot be used in a completely type safe way and so is banned in "
1519 ^"strict mode")
1521 let unset_nonidx_in_strict pos msgs =
1522 add_list Typing.unset_nonidx_in_strict
1523 ([pos, "In strict mode, unset is banned except on array or dict indexing"] @
1524 msgs)
1526 let unpacking_disallowed_builtin_function pos name =
1527 let name = Utils.strip_ns name in
1528 add Typing.unpacking_disallowed pos
1529 ("Arg unpacking is disallowed for "^name)
1531 let array_get_arity pos1 name pos2 =
1532 add_list Typing.array_get_arity [
1533 pos1, "You cannot use this "^(Utils.strip_ns name);
1534 pos2, "It is missing its type parameters"
1537 let typing_error pos msg =
1538 add Typing.generic_unify pos msg
1540 let typing_error_l err =
1541 add_error err
1543 let undefined_field p name =
1544 add Typing.undefined_field p ("The field "^name^" is undefined")
1546 let array_access pos1 pos2 ty =
1547 add_list Typing.array_access ((pos1,
1548 "This is not an object of type KeyedContainer, this is "^ty) ::
1549 if pos2 != Pos.none
1550 then [pos2, "You might want to check this out"]
1551 else [])
1553 let array_append pos1 pos2 ty =
1554 add_list Typing.array_append
1555 ((pos1, ty^" does not allow array append") ::
1556 if pos2 != Pos.none
1557 then [pos2, "You might want to check this out"]
1558 else [])
1560 let const_mutation pos1 pos2 ty =
1561 add_list Typing.const_mutation
1562 ((pos1, "You cannot mutate this") ::
1563 if pos2 != Pos.none
1564 then [(pos2, "This is " ^ ty)]
1565 else [])
1567 let expected_class ?(suffix="") pos =
1568 add Typing.expected_class pos ("Was expecting a class"^suffix)
1570 let snot_found_hint = function
1571 | `no_hint ->
1573 | `closest (pos, v) ->
1574 [pos, "The closest thing is "^v^" but it's not a static method"]
1575 | `did_you_mean (pos, v) ->
1576 [pos, "Did you mean: "^v]
1578 let string_of_class_member_kind = function
1579 | `class_constant -> "class constant"
1580 | `static_method -> "static method"
1581 | `class_variable -> "class variable"
1582 | `class_typeconst -> "type constant"
1584 let smember_not_found kind pos (cpos, class_name) member_name hint =
1585 let kind = string_of_class_member_kind kind in
1586 let class_name = strip_ns class_name in
1587 let msg = "Could not find "^kind^" "^member_name^" in type "^class_name in
1588 add_list Typing.smember_not_found
1589 ((pos, msg) :: (snot_found_hint hint
1590 @ [(cpos, "Declaration of "^class_name^" is here")]))
1592 let not_found_hint = function
1593 | `no_hint ->
1595 | `closest (pos, v) ->
1596 [pos, "The closest thing is "^v^" but it's a static method"]
1597 | `did_you_mean (pos, v) ->
1598 [pos, "Did you mean: "^v]
1600 let member_not_found kind pos (cpos, type_name) member_name hint reason =
1601 let type_name = strip_ns type_name in
1602 let kind =
1603 match kind with
1604 | `method_ -> "method"
1605 | `member -> "member"
1607 let msg = "Could not find "^kind^" "^member_name^" in an object of type "^
1608 type_name in
1609 add_list Typing.member_not_found
1610 ((pos, msg) :: (not_found_hint hint @ reason
1611 @ [(cpos, "Declaration of "^type_name^" is here")]))
1613 let parent_in_trait pos =
1614 add Typing.parent_in_trait pos
1615 ("parent:: inside a trait is undefined"
1616 ^" without 'require extends' of a class defined in <?hh")
1618 let parent_undefined pos =
1619 add Typing.parent_undefined pos
1620 "parent is undefined"
1622 let constructor_no_args pos =
1623 add Typing.constructor_no_args pos
1624 "This constructor expects no argument"
1626 let visibility p msg1 p_vis msg2 =
1627 add_list Typing.visibility [p, msg1; p_vis, msg2]
1629 let typing_too_many_args pos pos_def =
1630 add_list Typing.typing_too_many_args
1631 [pos, "Too many arguments"; pos_def, "Definition is here"]
1633 let typing_too_few_args pos pos_def =
1634 add_list Typing.typing_too_few_args
1635 [pos, "Too few arguments"; pos_def, "Definition is here"]
1637 let anonymous_recursive_call pos =
1638 add Typing.anonymous_recursive_call pos
1639 "recursive call to anonymous function"
1641 let bad_call pos ty =
1642 add Typing.bad_call pos
1643 ("This call is invalid, this is not a function, it is "^ty)
1645 let sketchy_null_check pos =
1646 add Typing.sketchy_null_check pos (
1647 "You are using a sketchy null check ...\n"^
1648 "Use is_null, or $x === null instead"
1651 let sketchy_null_check_primitive pos =
1652 add Typing.sketchy_null_check_primitive pos (
1653 "You are using a sketchy null check on a primitive type ...\n"^
1654 "Use is_null, or $x === null instead"
1657 let extend_final extend_pos decl_pos name =
1658 let name = (strip_ns name) in
1659 add_list Typing.extend_final [
1660 extend_pos, ("You cannot extend final class "^name);
1661 decl_pos, "Declaration is here"
1664 let read_before_write (pos, v) =
1665 add Typing.read_before_write pos (
1667 "Read access to $this->"; v; " before initialization"
1670 let interface_final pos =
1671 add Typing.interface_final pos
1672 "Interfaces cannot be final"
1674 let trait_final pos =
1675 add Typing.trait_final pos
1676 "Traits cannot be final"
1678 let implement_abstract ~is_final pos1 pos2 kind x =
1679 let name = "abstract "^kind^" '"^x^"'" in
1680 let msg1 =
1681 if is_final then
1682 "This class was declared as final. It must provide an implementation \
1683 for the "^name
1684 else
1685 "This class must be declared abstract, or provide an implementation \
1686 for the "^name in
1687 add_list Typing.implement_abstract [
1688 pos1, msg1;
1689 pos2, "Declaration is here";
1692 let generic_static pos x =
1693 add Typing.generic_static pos (
1694 "This static variable cannot use the type parameter "^x^"."
1697 let fun_too_many_args pos1 pos2 =
1698 add_list Typing.fun_too_many_args [
1699 pos1, "Too many mandatory arguments";
1700 pos2, "Because of this definition";
1703 let fun_too_few_args pos1 pos2 =
1704 add_list Typing.fun_too_few_args [
1705 pos1, "Too few arguments";
1706 pos2, "Because of this definition";
1709 let fun_unexpected_nonvariadic pos1 pos2 =
1710 add_list Typing.fun_unexpected_nonvariadic [
1711 pos1, "Should have a variadic argument";
1712 pos2, "Because of this definition";
1715 let fun_variadicity_hh_vs_php56 pos1 pos2 =
1716 add_list Typing.fun_variadicity_hh_vs_php56 [
1717 pos1, "Variadic arguments: ...-style is not a subtype of ...$args";
1718 pos2, "Because of this definition";
1721 let expected_tparam pos n =
1722 add Typing.expected_tparam pos (
1723 "Expected " ^
1724 (match n with
1725 | 0 -> "no type parameter"
1726 | 1 -> "a type parameter"
1727 | n -> string_of_int n ^ " type parameters"
1731 let object_string pos1 pos2 =
1732 add_list Typing.object_string [
1733 pos1, "You cannot use this object as a string";
1734 pos2, "This object doesn't implement __toString";
1737 let type_param_arity pos x n =
1738 add Typing.type_param_arity pos (
1739 "The type "^x^" expects "^n^" parameters"
1742 let cyclic_typedef p =
1743 add Typing.cyclic_typedef p
1744 "Cyclic typedef"
1746 let type_arity_mismatch pos1 n1 pos2 n2 =
1747 add_list Typing.type_arity_mismatch [
1748 pos1, "This type has "^n1^" arguments";
1749 pos2, "This one has "^n2;
1752 let this_final id pos2 (error: error) =
1753 let n = Utils.strip_ns (snd id) in
1754 let message1 = "Since "^n^" is not final" in
1755 let message2 = "this might not be a "^n in
1756 let code, msgl = (get_code error), (to_list error) in
1757 add_list code (msgl @ [(fst id, message1); (pos2, message2)])
1759 let exact_class_final id pos2 (error: error) =
1760 let n = Utils.strip_ns (snd id) in
1761 let message1 = "This requires the late-bound type to be exactly "^n in
1762 let message2 =
1763 "Since " ^n^" is not final this might be an instance of a child class" in
1764 let code, msgl = (get_code error), (to_list error) in
1765 add_list code (msgl @ [(fst id, message1); (pos2, message2)])
1767 let tuple_arity_mismatch pos1 n1 pos2 n2 =
1768 add_list Typing.tuple_arity_mismatch [
1769 pos1, "This tuple has "^n1^" elements";
1770 pos2, "This one has "^n2^" elements"
1773 let fun_arity_mismatch pos1 pos2 =
1774 add_list Typing.fun_arity_mismatch [
1775 pos1, "Number of arguments doesn't match";
1776 pos2, "Because of this definition";
1779 let discarded_awaitable pos1 pos2 =
1780 add_list Typing.discarded_awaitable [
1781 pos1, "This expression is of type Awaitable, but it's "^
1782 "either being discarded or used in a dangerous way before "^
1783 "being awaited";
1784 pos2, "This is why I think it is Awaitable"
1787 let gena_expects_array pos1 pos2 ty_str =
1788 add_list Typing.gena_expects_array [
1789 pos1, "gena expects an array";
1790 pos2, "It is incompatible with " ^ ty_str;
1793 let unify_error left right =
1794 add_list Typing.unify_error (left @ right)
1796 let static_dynamic static_position dyn_position method_name =
1797 let msg_static = "The function "^method_name^" is static" in
1798 let msg_dynamic = "It is defined as dynamic here" in
1799 add_list Typing.static_dynamic [
1800 static_position, msg_static;
1801 dyn_position, msg_dynamic
1804 let null_member s pos r =
1805 add_list Typing.null_member ([
1806 pos,
1807 "You are trying to access the member "^s^
1808 " but this object can be null. "
1809 ] @ r
1812 let non_object_member s pos1 ty pos2 =
1813 add_list Typing.non_object_member [
1814 pos1,
1815 ("You are trying to access the member "^s^
1816 " but this is not an object, it is "^
1817 ty);
1818 pos2,
1819 "Check this out"
1822 let null_container p null_witness =
1823 add_list Typing.null_container (
1826 "You are trying to access an element of this container"^
1827 " but the container could be null. "
1828 ] @ null_witness)
1830 let option_mixed pos =
1831 add Typing.option_mixed pos
1832 "?mixed is a redundant typehint - just use mixed"
1834 let declared_covariant pos1 pos2 emsg =
1835 add_list Typing.declared_covariant (
1836 [pos2, "Illegal usage of a covariant type parameter";
1837 pos1, "This is where the parameter was declared as covariant (+)"
1838 ] @ emsg
1841 let declared_contravariant pos1 pos2 emsg =
1842 add_list Typing.declared_contravariant (
1843 [pos2, "Illegal usage of a contravariant type parameter";
1844 pos1, "This is where the parameter was declared as contravariant (-)"
1845 ] @ emsg
1848 let cyclic_typeconst pos sl =
1849 let sl = List.map sl strip_ns in
1850 add Typing.cyclic_typeconst pos
1851 ("Cyclic type constant:\n "^String.concat " -> " sl)
1853 let this_lvalue pos =
1854 add Typing.this_lvalue pos "Cannot assign a value to $this"
1856 let abstract_concrete_override pos parent_pos kind =
1857 let kind_str = match kind with
1858 | `method_ -> "method"
1859 | `typeconst -> "type constant"
1860 | `constant -> "constant" in
1861 add_list Typing.abstract_concrete_override ([
1862 pos, "Cannot re-declare this " ^ kind_str ^ " as abstract";
1863 parent_pos, "Previously defined here"
1866 (*****************************************************************************)
1867 (* Typing decl errors *)
1868 (*****************************************************************************)
1870 let wrong_extend_kind child_pos child parent_pos parent =
1871 let msg1 = child_pos, child^" cannot extend "^parent in
1872 let msg2 = parent_pos, "This is "^parent in
1873 add_list Typing.wrong_extend_kind [msg1; msg2]
1875 let unsatisfied_req parent_pos req_name req_pos =
1876 let s1 = "Failure to satisfy requirement: "^(Utils.strip_ns req_name) in
1877 let s2 = "Required here" in
1878 if req_pos = parent_pos
1879 then add Typing.unsatisfied_req parent_pos s1
1880 else add_list Typing.unsatisfied_req [parent_pos, s1; req_pos, s2]
1882 let cyclic_class_def stack pos =
1883 let stack = SSet.fold (fun x y -> (Utils.strip_ns x)^" "^y) stack "" in
1884 add Typing.cyclic_class_def pos ("Cyclic class definition : "^stack)
1886 let override_final ~parent ~child =
1887 add_list Typing.override_final [child, "You cannot override this method";
1888 parent, "It was declared as final"]
1890 let should_be_override pos class_id id =
1891 add Typing.should_be_override pos
1892 ((Utils.strip_ns class_id)^"::"^id^"() is marked as override; \
1893 no non-private parent definition found \
1894 or overridden parent is defined in non-<?hh code")
1896 let override_per_trait class_name id m_pos =
1897 let c_pos, c_name = class_name in
1898 let err_msg =
1899 ("Method "^(Utils.strip_ns c_name)^"::"^id^" is should be an override \
1900 per the declaring trait; no non-private parent definition found \
1901 or overridden parent is defined in non-<?hh code")
1902 in add_list Typing.override_per_trait [
1903 c_pos, err_msg;
1904 m_pos, "Declaration of "^id^"() is here"
1907 let missing_assign pos =
1908 add Typing.missing_assign pos "Please assign a value"
1910 let private_override pos class_id id =
1911 add Typing.private_override pos ((Utils.strip_ns class_id)^"::"^id
1912 ^": combining private and override is nonsensical")
1914 let invalid_memoized_param pos ty_reason_msg =
1915 add_list Typing.invalid_memoized_param (
1916 ty_reason_msg @ [pos,
1917 "Parameters to memoized function must be null, bool, int, float, string, \
1918 an object deriving IMemoizeParam, or a Container thereof. See also \
1919 http://docs.hhvm.com/hack/attributes/special#__memoize"])
1921 let nullsafe_not_needed p nonnull_witness =
1922 add_list Typing.nullsafe_not_needed (
1925 "You are using the ?-> operator but this object cannot be null. "
1926 ] @ nonnull_witness)
1928 let generic_at_runtime p =
1929 add Typing.generic_at_runtime p
1930 "Generics can only be used in type hints since they are erased at runtime."
1932 let trivial_strict_eq p b left right left_trail right_trail =
1933 let msg = "This expression is always "^b in
1934 let left_trail = List.map left_trail typedef_trail_entry in
1935 let right_trail = List.map right_trail typedef_trail_entry in
1936 add_list Typing.trivial_strict_eq
1937 ((p, msg) :: left @ left_trail @ right @ right_trail)
1939 let trivial_strict_not_nullable_compare_null p result type_reason =
1940 let msg = "This expression is always "^result in
1941 add_list Typing.not_nullable_compare_null_trivial
1942 ((p, msg) :: type_reason)
1944 let void_usage p void_witness =
1945 let msg = "You are using the return value of a void function" in
1946 add_list Typing.void_usage ((p, msg) :: void_witness)
1948 let noreturn_usage p noreturn_witness =
1949 let msg = "You are using the return value of a noreturn function" in
1950 add_list Typing.noreturn_usage ((p, msg) :: noreturn_witness)
1952 let attribute_too_few_arguments pos x n =
1953 let n = string_of_int n in
1954 add Typing.attribute_too_few_arguments pos (
1955 "The attribute "^x^" expects at least "^n^" arguments"
1958 let attribute_too_many_arguments pos x n =
1959 let n = string_of_int n in
1960 add Typing.attribute_too_many_arguments pos (
1961 "The attribute "^x^" expects at most "^n^" arguments"
1964 let attribute_param_type pos x =
1965 add Typing.attribute_param_type pos (
1966 "This attribute parameter should be "^x
1969 let deprecated_use pos pos_def msg =
1970 add_list Typing.deprecated_use [
1971 pos, msg;
1972 pos_def, "Definition is here";
1975 let cannot_declare_constant kind pos (class_pos, class_name) =
1976 let kind_str =
1977 match kind with
1978 | `enum -> "an enum"
1979 | `trait -> "a trait"
1981 add_list Typing.cannot_declare_constant [
1982 pos, "Cannot declare a constant in "^kind_str;
1983 class_pos, (strip_ns class_name)^" was defined as "^kind_str^" here";
1986 let ambiguous_inheritance pos class_ origin (error: error) =
1987 let origin = strip_ns origin in
1988 let class_ = strip_ns class_ in
1989 let message = "This declaration was inherited from an object of type "^origin^
1990 ". Redeclare this member in "^class_^" with a compatible signature." in
1991 let code, msgl = (get_code error), (to_list error) in
1992 add_list code (msgl @ [pos, message])
1994 let explain_contravariance pos c_name error =
1995 let message = "Considering that this type argument is contravariant "^
1996 "with respect to " ^ strip_ns c_name in
1997 let code, msgl = (get_code error), (to_list error) in
1998 add_list code (msgl @ [pos, message])
2000 let explain_invariance pos c_name suggestion error =
2001 let message = "Considering that this type argument is invariant "^
2002 "with respect to " ^ strip_ns c_name ^ suggestion in
2003 let code, msgl = (get_code error), (to_list error) in
2004 add_list code (msgl @ [pos, message])
2006 let local_variable_modified_and_used pos_modified pos_used_l =
2007 let used_msg p = p, "And accessed here" in
2008 add_list Typing.local_variable_modifed_and_used
2009 ((pos_modified, "Unsequenced modification and access to local \
2010 variable. Modified here") ::
2011 List.map pos_used_l used_msg)
2013 let local_variable_modified_twice pos_modified pos_modified_l =
2014 let modified_msg p = p, "And also modified here" in
2015 add_list Typing.local_variable_modifed_twice
2016 ((pos_modified, "Unsequenced modifications to local variable. \
2017 Modified here") ::
2018 List.map pos_modified_l modified_msg)
2020 let assign_during_case p =
2021 add Typing.assign_during_case p
2022 "Don't assign to variables inside of case labels"
2024 let cyclic_enum_constraint pos =
2025 add Typing.cyclic_enum_constraint pos "Cyclic enum constraint"
2027 let invalid_classname p =
2028 add Typing.invalid_classname p "Not a valid class name"
2030 let illegal_type_structure pos errmsg =
2031 let msg =
2032 "The two arguments to typc_structure() must be:"
2033 ^"\n - first: ValidClassname::class or an object of that class"
2034 ^"\n - second: a single-quoted string literal containing the name"
2035 ^" of a type constant of that class"
2036 ^"\n"^errmsg in
2037 add Typing.illegal_type_structure pos msg
2039 let illegal_typeconst_direct_access pos =
2040 let msg =
2041 "Type constants cannot be directly accessed. "
2042 ^"Use type_structure(ValidClassname::class, 'TypeConstName') instead" in
2043 add Typing.illegal_type_structure pos msg
2045 let class_property_only_static_literal pos =
2046 let msg =
2047 "Initialization of class property must be a static literal expression." in
2048 add Typing.class_property_only_static_literal pos msg
2050 let reference_expr pos =
2051 let msg = "Cannot take a value by reference in strict mode." in
2052 add Typing.reference_expr pos msg
2054 (*****************************************************************************)
2055 (* Convert relative paths to absolute. *)
2056 (*****************************************************************************)
2058 let to_absolute = M.to_absolute
2060 (*****************************************************************************)
2061 (* Printing *)
2062 (*****************************************************************************)
2064 let to_json (error : Pos.absolute error_) =
2065 let error_code, msgl = (get_code error), (to_list error) in
2066 let elts = List.map msgl begin fun (p, w) ->
2067 let line, scol, ecol = Pos.info_pos p in
2068 Hh_json.JSON_Object [
2069 "descr", Hh_json.JSON_String w;
2070 "path", Hh_json.JSON_String (Pos.filename p);
2071 "line", Hh_json.int_ line;
2072 "start", Hh_json.int_ scol;
2073 "end", Hh_json.int_ ecol;
2074 "code", Hh_json.int_ error_code
2076 end in
2077 Hh_json.JSON_Object [ "message", Hh_json.JSON_Array elts ]
2079 let to_string = M.to_string
2081 (*****************************************************************************)
2082 (* Try if errors. *)
2083 (*****************************************************************************)
2085 let try_ f1 f2 =
2086 M.try_with_result f1 (fun _ l -> f2 l)
2088 let try_with_error f1 f2 =
2089 try_ f1 (fun err -> add_error err; f2())
2091 let try_add_err pos err f1 f2 =
2092 try_ f1 begin fun error ->
2093 let error_code, l = (get_code error), (to_list error) in
2094 add_list error_code ((pos, err) :: l);
2095 f2()
2098 let has_no_errors f =
2099 try_ (fun () -> f(); true) (fun _ -> false)
2101 (*****************************************************************************)
2102 (* Do. *)
2103 (*****************************************************************************)
2105 let do_ = M.do_
2107 let ignore_ f =
2108 snd (do_ f)
2110 let try_when f ~when_ ~do_ =
2111 M.try_with_result f begin fun result (error: error) ->
2112 if when_()
2113 then do_ error
2114 else add_error error;
2115 result
2118 (* Runs the first function that is expected to produce an error. If it doesn't
2119 * then we run the second function we are given
2121 let must_error f error_fun =
2122 let had_no_errors = try_with_error (fun () -> f(); true) (fun _ -> false) in
2123 if had_no_errors then error_fun();
2127 let errors_without_tracing =
2128 (module Errors_with_mode(NonTracingErrors) : Errors_sig.S)
2129 let errors_with_tracing =
2130 (module Errors_with_mode(TracingErrors) : Errors_sig.S)
2132 include (val (if Injector_config.use_error_tracing
2133 then errors_with_tracing
2134 else errors_without_tracing))