2 * Copyright (c) 2014, Facebook, Inc.
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.
13 (*****************************************************************************)
14 (* Errors accumulator. *)
15 (*****************************************************************************)
17 type error
= (Pos.t
* string) list
20 let (error_list
: t
ref) = ref []
23 error_list
:= [pos
, msg
] :: !error_list
25 let add_list pos_msg_l
=
26 error_list
:= pos_msg_l
:: !error_list
29 error_list
:= error
:: !error_list
31 let to_list (error
: error
) = (error
: (Pos.t
* string) list
)
32 let get_pos (error
: error
) = fst
(List.hd error
)
33 let filename (error
: error
) = Pos.filename (get_pos error
)
34 let make_error (x
: (Pos.t
* string) list
) = (x
: error
)
36 (*****************************************************************************)
38 (*****************************************************************************)
40 let fixme_format pos
=
41 add pos
"HH_FIXME wrong format, expected '/* HH_FIXME[ERROR_NUMBER] */'"
45 "You probably forgot to bind this type parameter right?\nAdd <"^x^
46 "> somewhere (after the function name definition, or after the class name)\nExamples: "^
"function foo<T> or class A<T>")
48 let unexpected_eof pos
=
49 add pos
"Unexpected end of file"
51 let missing_field pos1 pos2 name
=
53 [pos1
, "The field '"^name^
"' is missing";
54 pos2
, "The field '"^name^
"' is defined"]
56 let generic_class_var pos
=
57 add pos
"A class variable cannot be generic"
59 let explain_constraint pos name
(error
: error
) =
62 [pos
, "Considering the constraint on the type '"^name^
"'"]
65 let unexpected_arrow pos cname
=
66 add pos
("Keys may not be specified for " ^ cname ^
" initialization")
68 let missing_arrow pos cname
=
69 add pos
("Keys must be specified for " ^ cname ^
" initialization")
71 let disallowed_xhp_type pos name
=
72 add pos
(name ^
" is not a valid type. Use :xhp or XHPChild.")
75 add p
"Value is too large"
77 let unterminated_comment pos
=
78 add pos
"unterminated comment"
80 let unterminated_xhp_comment pos
=
81 add pos
"unterminated xhp comment"
83 let name_already_bound x p1 p2
=
84 let x = Utils.strip_ns
x in
86 p1
, "Name already bound: "^
x;
87 p2
, "Previous definition is here"
90 let method_name_already_bound p name
=
91 add p
("Method name already bound: "^name
)
93 let error_name_already_bound hhi_root name name_prev p p_prev
=
95 let name = Utils.strip_ns
name in
96 let name_prev = Utils.strip_ns
name_prev in
98 p
, "Name already bound: "^
name;
99 p_prev
, (if String.compare
name name_prev == 0
100 then "Previous definition is here"
101 else "Previous definition "^
name_prev^
" differs only in capitalization ")
104 "This appears to be defined in an hhi file included in your project "^
105 "root. The hhi files for the standard library are now a part of the "^
106 "typechecker and must be removed from your project. Typically, you can "^
107 "do this by deleting the \"hhi\" directory you copied into your "^
108 "project when first starting with Hack." in
109 (* unsafe_opt since init stack will refuse to continue if we don't have an
112 if str_starts_with p
.Pos.pos_file hhi_root
113 then errs @ [p_prev
, hhi_msg]
114 else if str_starts_with p_prev
.Pos.pos_file hhi_root
115 then errs @ [p
, hhi_msg]
119 let unbound_name p
x =
120 add p
("Unbound name: "^
(strip_ns
x))
122 let different_scope p
x p'
=
123 add_list [p
, ("The variable "^
x ^
" is defined");
124 p'
, ("But in a different scope")]
127 add p
("Undefined variable: "^
x)
129 let this_reserved pos
=
130 add pos
"The type parameter \"this\" is reserved"
132 let start_with_T pos
=
134 "Please make your type parameter start with the letter T (capital)"
136 let already_bound pos
x =
137 add pos
("Argument already bound: "^
x)
139 let unexpected_typedef pos def_pos
=
141 pos
, "Unexpected typedef";
142 def_pos
, "Definition is here";
145 let fd_name_already_bound pos
=
146 add pos
"Field name already bound"
148 let primitive_toplevel p
=
149 add p
("Primitive type annotations are always available and may no \
150 longer be referred to in the toplevel namespace.")
152 let integer_instead_of_int p
=
153 add p
"Invalid Hack type. Using \"integer\" in Hack is considered \
154 an error. Use \"int\" instead, to keep the codebase \
157 let boolean_instead_of_bool p
=
158 add p
"Invalid Hack type. Using \"boolean\" in Hack is considered \
159 an error. Use \"bool\" instead, to keep the codebase \
162 let double_instead_of_float p
=
163 add p
"Invalid Hack type. Using \"double\" in Hack is considered \
164 an error. Use \"float\" instead. They are equivalent data types \
165 and the codebase remains consistent."
167 let real_instead_of_float p
=
168 add p
"Invalid Hack type. Using \"real\" in Hack is considered \
169 an error. Use \"float\" instead. They are equivalent data types and \
170 the codebase remains consistent."
172 let this_no_argument p
=
173 add p
"\"this\" expects no arguments"
175 let this_outside_of_class p
=
176 add p
"Cannot use \"this\" outside of a class"
178 let this_must_be_return p
=
179 add p
"The type \"this\" can only be used as a return type, \
180 to instantiate a covariant type variable, \
181 or as a private non-static member variable"
183 let lowercase_this p
x =
184 add p
("Invalid Hack type \""^
x^
"\". Use \"this\" instead")
186 let tparam_with_tparam p
x =
187 add p
(Printf.sprintf
"%s is a type parameter. Type parameters cannot \
188 themselves take type parameters (e.g. %s<int> doesn't make sense)" x x)
190 let shadowed_type_param p pos
name =
192 p
, Printf.sprintf
"You cannot re-bind the type parameter %s" name;
193 pos
, Printf.sprintf
"%s is already bound here" name
196 let missing_typehint p
=
197 add p
"Please add a type hint"
199 let expected_variable p
=
200 add p
"Was expecting a variable name"
202 let naming_too_few_arguments p
=
203 add p
"Too few arguments"
205 let naming_too_many_arguments p
=
206 add p
"Too many arguments"
208 let expected_collection p cn
=
209 add p
("Unexpected collection type " ^
(Utils.strip_ns cn
))
211 let illegal_CLASS p
=
212 add p
"Using __CLASS__ outside a class"
214 let dynamic_method_call p
=
215 add p
"Dynamic method call"
218 let msg = "The argument to fun() must be a single-quoted, constant "^
219 "literal string representing a valid function name." in
222 let illegal_meth_fun p
=
223 let msg = "String argument to fun() contains ':';"^
224 " for static class methods, use"^
225 " class_meth(Cls::class, 'method_name'), not fun('Cls::method_name')" in
228 let illegal_inst_meth p
=
229 let msg = "The argument to inst_meth() must be an expression and a "^
230 "constant literal string representing a valid method name." in
233 let illegal_meth_caller p
=
235 "The two arguments to meth_caller() must be:"
236 ^
"\n - first: ClassOrInterface::class"
237 ^
"\n - second: a single-quoted string literal containing the name"
238 ^
" of a non-static method of that class" in
241 let illegal_class_meth p
=
243 "The two arguments to class_meth() must be:"
244 ^
"\n - first: ValidClassname::class"
245 ^
"\n - second: a single-quoted string literal containing the name"
246 ^
" of a static method of that class" in
250 add p
"assert expects exactly one argument"
253 add p
"gena() expects exactly 1 argument"
256 add p
"genva() expects at least 1 argument"
258 let gen_array_rec_arity p
=
259 add p
"gen_array_rec() expects exactly 1 argument"
261 let gen_array_va_rec_arity p
=
263 "gen_array_va_rec_DEPRECATED() expects at least 1 argument"
265 let dynamic_class p
=
266 add p
"Don't use dynamic classes"
268 let typedef_constraint pos
=
269 add pos
"Constraints on typedefs are not supported"
271 let add_a_typehint pos
=
272 add pos
"Please add a type hint"
274 let local_const var_pos
=
275 add var_pos
"You cannot use a local variable in a constant definition"
277 let illegal_constant pos
=
278 add pos
"Illegal constant value"
280 let cyclic_constraint p
=
281 add p
"Cyclic constraint"
283 let parsing_error (p
, msg) =
286 let format_string pos snippet s class_pos fname class_suggest
=
288 (pos
, "I don't understand the format string " ^ snippet ^
" in " ^ s
);
290 "You can add a new format specifier by adding "
291 ^fname^
"() to "^class_suggest
)]
293 let expected_literal_string pos
=
294 add pos
"This argument must be a literal string"
296 let generic_array_strict p
=
297 add p
"You cannot have an array without generics in strict mode"
299 let nullable_void p
=
300 add p
"?void is a nonsensical typehint"
303 add p
("Did you want a tuple? Try (X,Y), not tuple<X,Y>")
305 let class_arity pos class_name arity
=
306 add pos
("The class "^
(Utils.strip_ns class_name
)^
" expects "^
307 soi arity^
" arguments")
309 let dynamic_yield_private pos
=
311 [pos
, "DynamicYield cannot see private methods in subclasses"]
313 let expecting_type_hint p
=
314 add p
"Was expecting a type hint"
316 let expecting_type_hint_suggest p ty
=
317 add p
("Was expecting a type hint (what about: "^ty^
")")
319 let expecting_return_type_hint p
=
320 add p
"Was expecting a return type hint"
322 let expecting_return_type_hint_suggest p ty
=
323 add p
("Was expecting a return type hint (what about: ': "^ty^
"')")
325 let field_kinds p1 p2
=
326 add_list [p1
, "You cannot use this kind of field (value)";
327 p2
, "Mixed with this kind of field (key => value)"]
329 let unbound_name_typing pos
name =
330 add pos
("Unbound name, Typing: "^
(strip_ns
name))
332 let did_you_mean_naming pos
name suggest_pos suggest_name
=
333 add_list [pos
, "Could not find "^
(strip_ns
name) ;
334 suggest_pos
, "Did you mean "^
(strip_ns suggest_name
)^
"?"]
336 let previous_default p
=
338 ("A previous parameter has a default value.\n"^
339 "Remove all the default values for the preceding parameters,\n"^
340 "or add a default value to this one.")
342 let void_parameter p
=
343 add p
"Cannot have a void parameter"
345 let nullable_parameter pos
=
346 add pos
"Please add a ?, this argument can be null"
348 let return_in_void p1 p2
=
351 "You cannot return a value";
353 "This is a void function"
356 let this_in_static p
=
357 add p
"Don't use $this in a static method"
359 let this_outside_class p
=
360 add p
"Can't use $this outside of a class"
362 let unbound_global cst_pos
=
363 add cst_pos
"Unbound global constant (Typing)"
365 let private_inst_meth method_pos p
=
367 method_pos
, "This is a private method";
368 p
, "you cannot use it with inst_meth (whether you are in the same class or not)."
371 let protected_inst_meth method_pos p
=
373 method_pos
, "This is a protected method";
374 p
, "you cannot use it with inst_meth (whether you are in the same class hierarchy or not)."
377 let private_class_meth p1 p2
=
379 p1
, "This is a private method";
380 p2
, "you cannot use it with class_meth (whether you are in the same class or not)."
383 let protected_class_meth p1 p2
=
385 p1
, "This is a protected method";
386 p2
, "you cannot use it with class_meth (whether you are in the same class hierarchy or not)."
390 add p
"(array) cast forbidden in strict mode; arrays with unspecified \
391 key and value types are not allowed"
393 let anonymous_recursive p
=
394 add p
"Anonymous functions cannot be recursive"
396 let new_static_outside_class p
=
397 add p
"Can't use new static() outside of a class"
399 let new_self_outside_class p
=
400 add p
"Can't use new self() outside of a class"
402 let abstract_instantiate p cname
=
403 add p
("Can't instantiate " ^
Utils.strip_ns cname
)
406 add p
"A pair has exactly 2 elements"
408 let tuple_arity p2 size2 p1 size1
=
410 p2
, "This tuple has "^ string_of_int size2^
" elements";
411 p1
, string_of_int size1 ^
" were expected"]
413 let undefined_parent pos
=
414 add pos
"The parent class is undefined"
416 let parent_construct_in_trait pos
=
417 add pos
"Don't call parent::__construct from a trait"
419 let parent_outside_class pos
=
420 add pos
"parent is undefined outside of a class"
422 let dont_use_isset p
=
423 add p
"Don't use isset!"
425 let array_get_arity p1
name p2
=
427 p1
, "You cannot use this "^
(Utils.strip_ns
name);
428 p2
, "It is missing its type parameters"
431 let static_overflow p
=
432 add p
"Static integer overflow"
434 let typing_error p
msg =
437 let typing_error_l err
=
440 let undefined_field p
name =
441 add p
("The field "^
name^
" is undefined")
444 add p
"Was expecting a constant string (for shape access)"
446 let array_access p1 p2 ty
=
447 add_list ((p1
, "This is not a container, this is "^ty
) ::
449 then [p2
, "You might want to check this out"]
452 let array_append p1 p2 ty
=
453 add_list ((p1
, ty^
" does not allow array append") ::
455 then [p2
, "You might want to check this out"]
458 let const_mutation p1 p2 ty
=
459 add_list ((p1
, "You cannot mutate this") ::
461 then [(p2
, "This is " ^ ty
)]
464 let negative_tuple_index p
=
465 add p
"You cannot use a negative value here"
467 let tuple_index_too_large p
=
468 add p
"Cannot access this field"
470 let expected_static_int p
=
471 add p
"Please use a static integer"
473 let expected_class p
=
474 add p
"Was expecting a class"
476 let snot_found_hint = function
479 | `closest
(pos
, v
) ->
480 [pos
, "The closest thing is "^v^
" but it's not a static method"]
481 | `did_you_mean
(pos
, v
) ->
482 [pos
, "Did you mean: "^v
]
484 let string_of_class_member_kind = function
485 | `class_constant
-> "class constant"
486 | `static_method
-> "static method"
487 | `class_variable
-> "class variable"
489 let smember_not_found kind pos member_name hint
=
490 let kind = string_of_class_member_kind kind in
491 add_list ((pos
, "Could not find "^
kind^
" "^member_name
)
492 :: snot_found_hint hint
)
494 let not_found_hint = function
497 | `closest
(pos
, v
) ->
498 [pos
, "The closest thing is "^v^
" but it's a static method"]
499 | `did_you_mean
(pos
, v
) ->
500 [pos
, "Did you mean: "^v
]
502 let member_not_found kind pos
(cpos
, class_name
) member_name hint
=
505 | `method_
-> "method "
506 | `member
-> "member "
508 let msg = "The "^
kind^member_name^
" is undefined "
509 ^
"in an object of type "^
(strip_ns class_name
)
512 ((pos
, msg) :: (cpos
, "Check this out") ::
515 let parent_in_trait p
=
517 ("parent:: inside a trait is undefined"
518 ^
" without 'require extends' of a class defined in <?hh")
520 let parent_undefined p
=
521 add p
"parent is undefined"
523 let constructor_no_args p
=
524 add p
"This constructor expects no argument"
526 let visibility p msg1 p_vis msg2
=
527 add_list [p
, msg1
; p_vis
, msg2
]
529 let typing_too_many_args pos pos_def
=
530 add_list [pos
, "Too many arguments"; pos_def
, "Definition is here"]
532 let typing_too_few_args pos pos_def
=
533 add_list [pos
, "Too few arguments"; pos_def
, "Definition is here"]
535 let anonymous_recursive_call pos
=
536 add pos
"recursive call to anonymous function"
539 add p
("This call is invalid, this is not a function, it is "^ty
)
541 let sketchy_null_check p
=
542 add p
("You are using a sketchy null check ...\n"^
543 "Use is_null, or $x === null instead")
545 let sketchy_null_check_primitive p
=
547 ("You are using a sketchy null check on a primitive type ...\n"^
548 "Use is_null, or $x === null instead")
550 let extend_final position
=
551 add position
"You cannot extend a class declared as final"
553 let read_before_write (p
, v
) =
556 "Read access to $this->"; v
; " before initialization"
559 let interface_final pos
=
560 add pos
"Interfaces cannot be final"
562 let abstract_class_final pos
=
563 add pos
"Abstract classes cannot be final"
565 let trait_final pos
=
566 add pos
"Traits cannot be final"
568 let implement_abstract p1 p2
x =
569 let s_meth = "abstract method "^
x in
570 add_list [p1
, "This class must provide an implementation for the "^
s_meth;
571 p2
, "The "^
s_meth^
" is defined here"]
573 let generic_static p
x =
574 add p
("This static variable cannot use the type parameter "^
x^
".")
576 let fun_too_many_args p1 p2
=
577 add_list [p1
, "Too many mandatory arguments";
578 p2
, "Because of this definition"]
580 let fun_too_few_args p1 p2
=
581 add_list [p1
, "Too few arguments";
582 p2
, "Because of this definition"]
584 let fun_unexpected_nonvariadic p1 p2
=
585 add_list [p1
, "Should have a variadic argument";
586 p2
, "Because of this definition"]
588 let fun_variadicity_hh_vs_php56 p1 p2
=
589 add_list [p1
, "Variadic arguments: ...-style is not a subtype of ...$args";
590 p2
, "Because of this definition"]
592 let expected_tparam pos n
=
593 add pos
("Expected " ^
595 | 0 -> "no type parameter"
596 | 1 -> "a type parameter"
597 | n
-> string_of_int n ^
" type parameters"
600 let field_missing k p1 p2
=
601 add_list [p2
, "The field '"^k^
"' is defined";
602 p1
, "The field '"^k^
"' is missing"]
604 let object_string p1 p2
=
606 p1
, "You cannot use this object as a string";
607 p2
, "This object doesn't implement __toString"]
609 let type_param_arity pos
x n
=
610 add pos
("The type "^
x^
" expects "^n^
" parameters")
612 let cyclic_typedef p
=
613 add p
"Cyclic typedef"
615 let type_arity_mismatch p1 n1 p2 n2
=
616 add_list [p1
, "This type has "^n1^
" arguments";
617 p2
, "This one has "^n2
]
619 let this_final id p2
(error
: error
) =
620 let n = Utils.strip_ns
(snd id
) in
621 let message1 = "Since "^
n^
" is not final" in
622 let message2 = "this might not be a "^
n in
623 add_list (error
@ [(fst id
, message1); (p2
, message2)])
625 let tuple_arity_mismatch p1 n1 p2 n2
=
626 add_list [p1
, "This tuple has "^n1^
" elements";
627 p2
, "This one has "^n2^
" elements"]
629 let fun_arity_mismatch p1 p2
=
630 add_list [p1
, "Number of arguments doesn't match";
631 p2
, "Because of this definition"]
633 let discarded_awaitable p1 p2
=
635 p1
, "This expression is of type Awaitable, but it's "^
636 "either being discarded or used in a dangerous way before "^
638 p2
, "This is why I think it is Awaitable"
641 let gena_expects_array p1 p2 ty_str
=
643 p1
, "gena expects an array";
644 p2
, "It is incompatible with " ^ ty_str
;
647 let unify_error left right
=
648 add_list (left
@ right
)
650 let static_dynamic static_position dyn_position method_name
=
651 let msg_static = "The function "^method_name^
" is static" in
652 let msg_dynamic = "It is defined as dynamic here" in
653 add_list [static_position
, msg_static; dyn_position
, msg_dynamic]
655 let null_member s p r
=
658 "You are trying to access the member "^s^
659 " but this object can be null. "
663 let non_object_member s p1 ty p2
=
665 ("You are trying to access the member "^s^
666 " but this is not an object, it is "^
671 let null_container p null_witness
=
675 "You are trying to access an element of this container"^
676 " but the container could be null. "
679 let option_mixed pos
=
680 add pos
"?mixed is a redundant typehint - just use mixed"
682 (*****************************************************************************)
683 (* Typing decl errors *)
684 (*****************************************************************************)
686 let wrong_extend_kind child_pos child parent_pos parent
=
687 let msg1 = child_pos
, child^
" cannot extend "^parent
in
688 let msg2 = parent_pos
, "This is "^parent
in
689 add_list [msg1; msg2]
691 let unsatisfied_req parent_pos req_name req_pos
=
692 let s1 = "Failure to satisfy requirement: "^
(Utils.strip_ns req_name
) in
693 let s2 = "Required here" in
694 if req_pos
= parent_pos
then add parent_pos
s1
695 else add_list [parent_pos
, s1; req_pos
, s2]
697 let cyclic_class_def stack pos
=
698 let stack = SSet.fold
(fun x y
-> (Utils.strip_ns
x)^
" "^y
) stack "" in
699 add pos
("Cyclic class definition : "^
stack)
701 let override_final ~parent ~child
=
702 add_list [child
, "You cannot override this method";
703 parent
, "It was declared as final"]
705 let should_be_override pos class_id id
=
707 ((Utils.strip_ns class_id
)^
"::"^id^
"() is marked as override; \
708 no non-private parent definition found \
709 or overridden parent is defined in non-<?hh code")
711 let override_per_trait class_name id m_pos
=
712 let c_pos, c_name
= class_name
in
714 ("Method "^
(Utils.strip_ns c_name
)^
"::"^id^
" is should be an override \
715 per the declaring trait; no non-private parent definition found \
716 or overridden parent is defined in non-<?hh code")
719 m_pos
, "Declaration of "^id^
"() is here"
722 let missing_assign pos
=
723 add pos
"Please assign a value"
725 let private_override pos class_id id
=
726 add pos
((Utils.strip_ns class_id
)^
"::"^id
727 ^
": combining private and override is nonsensical")
729 (*****************************************************************************)
730 (* Init check errors *)
731 (*****************************************************************************)
733 let no_construct_parent p
=
734 add p
(sl
["You are extending a class that needs to be initialized\n";
735 "Make sure you call parent::__construct.\n"
738 let not_initialized (p
, c
) =
739 if c
= "parent::__construct" then no_construct_parent p
else
741 "The class member "; c
;" is not always properly initialized\n";
742 "Make sure you systematically set $this->"; c
;
743 " when the method __construct is called\n";
744 "Alternatively, you can define the type as optional (?...)\n"
747 let call_before_init p cv
=
750 "Until the initialization of $this is over,";
751 " you can only call private methods\n";
752 "The initialization is not over because ";
754 if cv
= "parent::__construct"
755 then ["you forgot to call parent::__construct"]
756 else ["$this->"; cv
; " can still potentially be null"])
759 (*****************************************************************************)
760 (* Nast errors check *)
761 (*****************************************************************************)
763 let type_arity pos
name nargs
=
765 (sl
["The type ";(Utils.strip_ns
name);" expects ";nargs
;" type parameter(s)"])
767 let abstract_outside (p
, _
) =
769 "This method is declared as abstract, in a class that isn't"
771 let invalid_req_implements p
=
772 add p
"Only traits may use 'require implements'"
774 let invalid_req_extends p
=
775 add p
"Only traits and interfaces may use 'require extends'"
777 let interface_with_body (p
, _
) =
779 "A method cannot have a body in an interface"
781 let abstract_with_body (p
, _
) =
783 "This method is declared as abstract, but has a body"
785 let not_abstract_without_body (p
, _
) =
787 "This method is not declared as abstract, it must have a body"
789 let return_in_gen p
=
791 ("Don't use return in a generator (a generator"^
792 " is a function that uses yield)")
794 let return_in_finally p
=
796 ("Don't use return in a finally block;"^
797 " there's nothing to receive the return value")
799 let yield_in_async_function p
=
801 "Don't use yield in an async function"
803 let await_in_sync_function p
=
805 "await can only be used inside async functions"
809 ("Don't call "^s^
" it's one of these magic things we want to avoid")
811 let non_interface (p
: Pos.t
) (c2
: string) (verb
: string): 'a
=
812 add p
("Cannot " ^ verb ^
" " ^
(strip_ns c2
) ^
" - it is not an interface")
814 let toString_returns_string pos
=
815 add pos
"__toString should return a string"
817 let toString_visibility pos
=
818 add pos
"__toString must have public visibility and cannot be static"
820 let uses_non_trait (p
: Pos.t
) (n: string) (t
: string) =
821 add p
((Utils.strip_ns
n) ^
" is not a trait. It is " ^ t ^
".")
823 let requires_non_class (p
: Pos.t
) (n: string) (t
: string) =
824 add p
((Utils.strip_ns
n) ^
" is not a class. It is " ^ t ^
".")
826 let abstract_body pos
=
827 add pos
"This method shouldn't have a body"
829 let not_public_interface pos
=
830 add pos
"Access type for interface method must be public"
832 let interface_with_member_variable pos
=
833 add pos
"Interfaces cannot have member variables"
835 let interface_with_static_member_variable pos
=
836 add pos
"Interfaces cannot have static variables"
838 let dangerous_method_name p
=
839 add p
("This is a dangerous method name, "^
840 "if you want to define a constructor, use "^
843 (*****************************************************************************)
844 (* Nast terminality *)
845 (*****************************************************************************)
847 let case_fallthrough p1 p2
=
849 p1
, ("This switch has a case that implicitly falls through and is "^
850 "not annotated with // FALLTHROUGH");
851 p2
, "This case implicitly falls through"
854 let default_fallthrough p
=
856 ("This switch has a default case that implicitly falls "^
857 "through and is not annotated with // FALLTHROUGH")
859 (*****************************************************************************)
860 (* Typing inheritance *)
861 (*****************************************************************************)
863 let visibility_extends vis pos parent_pos parent_vis
=
864 let msg1 = pos
, "This member visibility is: " ^ vis
in
865 let msg2 = parent_pos
, parent_vis ^
" was expected" in
866 add_list [msg1; msg2]
868 let member_not_implemented member_name parent_pos pos defn_pos
=
869 let msg1 = pos
, "This object doesn't implement the method "^member_name
in
870 let msg2 = parent_pos
, "Which is required by this interface" in
871 let msg3 = defn_pos
, "As defined here" in
872 add_list [msg1; msg2; msg3]
874 let override parent_pos parent_name pos
name (error
: error
) =
875 let msg1 = pos
, ("This object is of type "^
(strip_ns
name)) in
876 let msg2 = parent_pos
,
877 ("It is incompatible with this object of type "^
(strip_ns parent_name
)^
878 "\nbecause some of their methods are incompatible."^
879 "\nRead the following to see why:"
881 (* This is a cascading error message *)
882 add_list (msg1 :: msg2 :: error
)
884 let missing_constructor pos
=
885 add pos
"The constructor is not implemented"
887 (*****************************************************************************)
889 (*****************************************************************************)
891 let typedef_trail_entry pos
= pos
, "Typedef definition comes from here"
893 let add_with_trail errs trail
=
894 add_list (errs @ List.map
typedef_trail_entry trail
)
896 let enum_constant_type_bad pos ty_pos ty trail
=
898 [pos
, "Enum constants must be an int or string";
902 let enum_type_bad pos ty trail
=
904 [pos
, "Enums must have int, string, or mixed type, not " ^ ty
]
907 let enum_type_typedef_mixed pos
=
908 add pos
"Can't use typedef that resolves to mixed in Enum"
910 (*****************************************************************************)
912 (*****************************************************************************)
913 let invalid_shape_field_name p
=
915 "Was expecting a constant string or class constant (for shape access)"
917 let invalid_shape_field_type pos ty_pos ty trail
=
919 [pos
, "A shape field name must be an int or string";
923 let invalid_shape_field_literal key_pos witness_pos
=
924 add_list [key_pos
, "Shape uses literal string as field name";
925 witness_pos
, "But expected a class constant"]
927 let invalid_shape_field_const key_pos witness_pos
=
928 add_list [key_pos
, "Shape uses class constant as field name";
929 witness_pos
, "But expected a literal string"]
931 let shape_field_class_mismatch key_pos witness_pos key_class witness_class
=
933 [key_pos
, "Shape field name is class constant from " ^ key_class
;
934 witness_pos
, "But expected constant from " ^ witness_class
]
936 let shape_field_type_mismatch key_pos witness_pos key_ty witness_ty
=
938 [key_pos
, "Shape field name is " ^ key_ty ^
" class constant";
939 witness_pos
, "But expected " ^ witness_ty
]
941 (*****************************************************************************)
943 (*****************************************************************************)
945 let to_json (e
: error
) = Hh_json.(
946 let elts = List.map
(fun (p
, w
) ->
947 let line, scol
, ecol
= Pos.info_pos p
in
948 JAssoc
[ "descr", JString w
;
949 "path", JString p
.Pos.pos_file
;
956 JAssoc
[ "message", JList
elts ]
959 let to_string (e
: error
) : string =
960 let buf = Buffer.create
50 in
963 | (pos1
, msg1) :: rest_of_error
->
964 Buffer.add_string
buf begin
965 Printf.sprintf
"%s\n%s\n" (Pos.string pos1
) msg1
967 List.iter
begin fun (p
, w
) ->
968 let msg = Printf.sprintf
"%s\n%s\n" (Pos.string p
) w
in
969 Buffer.add_string
buf msg
974 (*****************************************************************************)
976 (*****************************************************************************)
979 let error_list_copy = !error_list
in
981 let result = f1
() in
982 let errors = !error_list
in
983 error_list
:= error_list_copy;
984 match List.rev
errors with
988 let try_with_error f1 f2
=
989 try_ f1
(fun err
-> add_error err
; f2
())
991 let try_add_err pos err f1 f2
=
992 try_ f1
begin fun l
->
993 add_list ((pos
, err
) :: l
);
997 (*****************************************************************************)
999 (*****************************************************************************)
1002 let error_list_copy = !error_list
in
1004 let result = f
() in
1005 let out_errors = !error_list
in
1006 error_list
:= error_list_copy;
1007 List.rev
out_errors, result
1009 let try_when f ~when_ ~
do_ =
1010 try_ f
begin fun (error
: error
) ->
1013 else add_error error