diff --git a/infer/src/nullsafe/models.ml b/infer/src/nullsafe/models.ml index dc06c7d36..62ac731ab 100644 --- a/infer/src/nullsafe/models.ml +++ b/infer/src/nullsafe/models.ml @@ -9,8 +9,6 @@ open! IStd module Hashtbl = Caml.Hashtbl open ModelTables -(** Module for standard library models. *) - (** Unique representation of a method signature in form of a string. *) let to_unique_id proc_name = Procname.to_unique_id (Procname.Java proc_name) @@ -54,8 +52,6 @@ let get_special_method_modelled_nullability tenv java_proc_name = else None -(** Return the annotated signature of the procedure, taking into account models. External models - take precedence over internal ones. *) let get_modelled_annotated_signature ~is_callee_in_trust_list tenv proc_attributes = let proc_name = Procname.as_java_exn proc_attributes.ProcAttributes.proc_name @@ -99,50 +95,37 @@ let get_modelled_annotated_signature ~is_callee_in_trust_list tenv proc_attribut annotated_signature |> correct_by_internal_models |> correct_by_external_models -(** Check if the procedure is one of the known methods asserting nullability of the object. Nullsafe - should understand that both the argument and return value are non-nullable after the call. *) let is_check_not_null proc_name = table_has_procedure check_not_null_table proc_name || match_method_name proc_name "checkNotNull" -(** Parameter number (starting from 1) for a procedure known to produce a non-nullable assertion. - [None] if the function is not known to be an aseertion OR the parameter number is not known *) let get_check_not_null_parameter proc_name = let proc_id = to_unique_id proc_name in Hashtbl.find_opt check_not_null_parameter_table proc_id -(** Check if the procedure is one of the known Preconditions.checkState. *) let is_check_state proc_name = table_has_procedure check_state_table proc_name || match_method_name proc_name "checkState" -(** Check if the procedure is one of the known Preconditions.checkArgument. *) let is_check_argument proc_name = table_has_procedure check_argument_table proc_name || match_method_name proc_name "checkArgument" -(** Check if the procedure does not return. *) let is_noreturn proc_name = table_has_procedure noreturn_table proc_name -(** Check if the procedure returns true on null. *) let is_true_on_null proc_name = table_has_procedure true_on_null_table proc_name -(** Check if the procedure returns false on null. *) let is_false_on_null proc_name = (* The only usecase for now - consider all overrides of `Object.equals()` correctly implementing the Java specification contract (returning false on null). *) PatternMatch.Java.is_override_of_lang_object_equals (Procname.Java proc_name) -(** Check if the procedure is Map.containsKey(). *) let is_containsKey proc_name = table_has_procedure containsKey_table proc_name -(** Check if the procedure is Map.put(). *) let is_mapPut proc_name = table_has_procedure mapPut_table proc_name -(** Check if a (nullable) method has a non-nullable alternative: A method that does the same as - [proc_name] but asserts the result is not null before returning to the caller. *) let find_nonnullable_alternative proc_name = (* NOTE: For now we fetch this info from internal models. It is a good idea to support this feature in a user-facing third party repository. *) @@ -150,7 +133,6 @@ let find_nonnullable_alternative proc_name = Hashtbl.find_opt nonnull_alternatives_table proc_id -(* Check if a given field is known to be a non-nullable *) let is_field_nonnullable field_name = Hashtbl.find_opt field_nullability_table (Fieldname.to_full_string field_name) |> Option.value_map ~f:(fun is_nullable -> not is_nullable) ~default:false diff --git a/infer/src/nullsafe/models.mli b/infer/src/nullsafe/models.mli new file mode 100644 index 000000000..24ec88414 --- /dev/null +++ b/infer/src/nullsafe/models.mli @@ -0,0 +1,52 @@ +(* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + *) + +open! IStd + +(** Methods dealing with specific knowledge about code in important third libraries, standard + libraries, etc *) + +val get_modelled_annotated_signature : + is_callee_in_trust_list:bool -> Tenv.t -> ProcAttributes.t -> AnnotatedSignature.t +(** Return the annotated signature of the procedure, taking into account models. External models + take precedence over internal ones. *) + +val is_check_not_null : Procname.Java.t -> bool +(** Check if the procedure is one of the known methods asserting nullability of the object. Nullsafe + should understand that both the argument and return value are non-nullable after the call. *) + +val get_check_not_null_parameter : Procname.Java.t -> int option +(** Parameter number (starting from 1) for a procedure known to produce a non-nullable assertion. + [None] if the function is not known to be an aseertion OR the parameter number is not known *) + +val is_check_state : Procname.Java.t -> bool +(** Check if the procedure is one of the known Preconditions.checkState. *) + +val is_check_argument : Procname.Java.t -> bool +(** Check if the procedure is one of the known Preconditions.checkArgument. *) + +val is_noreturn : Procname.Java.t -> bool +(** Check if the procedure does not return. *) + +val is_true_on_null : Procname.Java.t -> bool +(** Check if the procedure returns true on null. *) + +val is_false_on_null : Procname.Java.t -> bool +(** Check if the procedure returns false on null. *) + +val is_containsKey : Procname.Java.t -> bool +(** Check if the procedure is Map.containsKey(). *) + +val is_mapPut : Procname.Java.t -> bool +(** Check if the procedure is Map.put(). *) + +val find_nonnullable_alternative : Procname.Java.t -> ModelTables.nonnull_alternative_method option +(** Check if a (nullable) method has a non-nullable alternative: A method that does the same as + [proc_name] but asserts the result is not null before returning to the caller. *) + +val is_field_nonnullable : Fieldname.t -> bool +(** Check if a given field is known to be a non-nullable *)