From 43586dd8c59c95e4442a5fbaad7a22232bac1a59 Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Wed, 29 Apr 2020 03:00:06 -0700 Subject: [PATCH] [biabd] stop depending on nullsafe Summary: Based on a shrewd observation by mityal, we can copy a little bit of code from nullsafe and cut the dependency between biabduction and nullsafe. The trick was to notice that biabduction doesn't use the full power of the functions it was calling. Reviewed By: mityal Differential Revision: D21282656 fbshipit-source-id: 906847c26 --- infer/src/IR/ProcAttributes.ml | 26 +++++++++++++- infer/src/IR/ProcAttributes.mli | 2 ++ infer/src/biabduction/Rearrange.ml | 14 +++++--- infer/src/nullsafe/AnnotatedSignature.ml | 43 ++++------------------- infer/src/nullsafe/AnnotatedSignature.mli | 3 -- infer/src/nullsafe/models.ml | 21 ----------- 6 files changed, 44 insertions(+), 65 deletions(-) diff --git a/infer/src/IR/ProcAttributes.ml b/infer/src/IR/ProcAttributes.ml index e078ac21d..2c356f43a 100644 --- a/infer/src/IR/ProcAttributes.ml +++ b/infer/src/IR/ProcAttributes.ml @@ -66,6 +66,26 @@ type t = ; ret_type: Typ.t (** return type *) ; has_added_return_param: bool (** whether or not a return param was added *) } +let get_annotated_formals {method_annotation= {params}; formals} = + let rec zip_params ial parl = + match (ial, parl) with + | ia :: ial', param :: parl' -> + (param, ia) :: zip_params ial' parl' + | [], param :: parl' -> + (* List of annotations exhausted before the list of params - + treat lack of annotation info as an empty annotation *) + (param, Annot.Item.empty) :: zip_params [] parl' + | [], [] -> + [] + | _ :: _, [] -> + (* List of params exhausted before the list of annotations - + this should never happen *) + assert false + in + (* zip formal params with annotation *) + List.rev (zip_params (List.rev params) (List.rev formals)) + + let default translation_unit proc_name = { access= PredSymb.Default ; captured= [] @@ -150,7 +170,11 @@ let pp f pp_bool_default ~default:default.is_defined "is_defined" is_defined f () ; pp_bool_default ~default:default.is_java_synchronized_method "is_java_synchronized_method" is_java_synchronized_method f () ; - if not ([%compare.equal : Procname.t option] default.passed_as_noescape_block_to passed_as_noescape_block_to) then + if + not + ([%compare.equal: Procname.t option] default.passed_as_noescape_block_to + passed_as_noescape_block_to) + then F.fprintf f "; passed_as_noescape_block_to %a" (Pp.option Procname.pp) passed_as_noescape_block_to ; pp_bool_default ~default:default.is_no_return "is_no_return" is_no_return f () ; diff --git a/infer/src/IR/ProcAttributes.mli b/infer/src/IR/ProcAttributes.mli index 4190eda8e..d8ffb288d 100644 --- a/infer/src/IR/ProcAttributes.mli +++ b/infer/src/IR/ProcAttributes.mli @@ -55,4 +55,6 @@ val default : SourceFile.t -> Procname.t -> t val pp : Format.formatter -> t -> unit +val get_annotated_formals : t -> ((Mangled.t * Typ.t) * Annot.Item.t) list + module SQLite : SqliteUtils.Data with type t = t diff --git a/infer/src/biabduction/Rearrange.ml b/infer/src/biabduction/Rearrange.ml index 327585041..221fe2dd9 100644 --- a/infer/src/biabduction/Rearrange.ml +++ b/infer/src/biabduction/Rearrange.ml @@ -1144,11 +1144,17 @@ let rec iter_rearrange analysis_data pname tenv lexp typ_from_instr prop iter in res +let param_has_annot predicate pvar params_with_annotations = + List.exists + ~f:(function + | (mangled, _), param_annotation_deprecated -> + Mangled.equal mangled (Pvar.get_name pvar) && predicate param_annotation_deprecated ) + params_with_annotations + + let var_has_annotation pdesc is_annotation pvar = - let ann_sig = - Models.get_modelled_annotated_signature_for_biabduction (Procdesc.get_attributes pdesc) - in - AnnotatedSignature.param_has_annot is_annotation pvar ann_sig + Procdesc.get_attributes pdesc |> ProcAttributes.get_annotated_formals + |> param_has_annot is_annotation pvar let attr_has_annot is_annotation tenv prop exp = diff --git a/infer/src/nullsafe/AnnotatedSignature.ml b/infer/src/nullsafe/AnnotatedSignature.ml index 29de7753d..206124deb 100644 --- a/infer/src/nullsafe/AnnotatedSignature.ml +++ b/infer/src/nullsafe/AnnotatedSignature.ml @@ -75,37 +75,15 @@ let extract_nullability ~is_callee_in_trust_list ~nullsafe_mode ~is_third_party (return_nullability, params_nullability) -let get ~is_callee_in_trust_list ~nullsafe_mode proc_attributes : t = - let Annot.Method.{return= ret_annotation; params= original_params_annotation} = - proc_attributes.ProcAttributes.method_annotation - in - let formals = proc_attributes.ProcAttributes.formals in - let ret_type = proc_attributes.ProcAttributes.ret_type in - let procname = proc_attributes.ProcAttributes.proc_name in +let get ~is_callee_in_trust_list ~nullsafe_mode + ( {ProcAttributes.proc_name; ret_type; method_annotation= {return= ret_annotation}} as + proc_attributes ) : t = let is_third_party = ThirdPartyAnnotationInfo.is_third_party_proc (ThirdPartyAnnotationGlobalRepo.get_repo ()) - procname - in - (* zip formal params with annotation *) - let params_with_annotations = - let rec zip_params ial parl = - match (ial, parl) with - | ia :: ial', param :: parl' -> - (param, ia) :: zip_params ial' parl' - | [], param :: parl' -> - (* List of annotations exhausted before the list of params - - treat lack of annotation info as an empty annotation *) - (param, Annot.Item.empty) :: zip_params [] parl' - | [], [] -> - [] - | _ :: _, [] -> - (* List of params exhausted before the list of annotations - - this should never happen *) - assert false - in - List.rev (zip_params (List.rev original_params_annotation) (List.rev formals)) + proc_name in + let params_with_annotations = ProcAttributes.get_annotated_formals proc_attributes in let param_annotated_types = List.map params_with_annotations ~f:(fun ((_, typ), annotations) -> (typ, annotations)) in @@ -143,13 +121,6 @@ let get_for_class_under_analysis tenv proc_attributes = {result with nullsafe_mode} -let param_has_annot predicate pvar ann_sig = - List.exists - ~f:(fun {mangled; param_annotation_deprecated} -> - Mangled.equal mangled (Pvar.get_name pvar) && predicate param_annotation_deprecated ) - ann_sig.params - - let pp proc_name fmt annotated_signature = let pp_ia fmt ia = if not (List.is_empty ia) then F.fprintf fmt "%a " Annot.Item.pp ia in let pp_annotated_param fmt {mangled; param_annotation_deprecated; param_annotated_type} = @@ -171,8 +142,8 @@ let mk_ia_nullable ia = let mark_ia_nullability ia x = if x then mk_ia_nullable ia else ia -(* Override existing information about nullability for a given type and - set it to either nullable or nonnull *) +(** Override existing information about nullability for a given type and set it to either nullable + or nonnull *) let set_modelled_nullability_for_annotated_type annotated_type should_set_nullable = let nullability = if should_set_nullable then AnnotatedNullability.Nullable ModelledNullable diff --git a/infer/src/nullsafe/AnnotatedSignature.mli b/infer/src/nullsafe/AnnotatedSignature.mli index cbd2f61b0..54b76342e 100644 --- a/infer/src/nullsafe/AnnotatedSignature.mli +++ b/infer/src/nullsafe/AnnotatedSignature.mli @@ -28,9 +28,6 @@ and param_signature = and model_source = InternalModel | ThirdPartyRepo of {filename: string; line_number: int} [@@deriving compare] -val param_has_annot : (Annot.Item.t -> bool) -> Pvar.t -> t -> bool -(** Check if the given parameter has an annotation in the given signature *) - val set_modelled_nullability : Procname.t -> t -> model_source -> bool * bool list -> t (** Override nullability for a function signature given its modelled nullability (for ret value and params) *) diff --git a/infer/src/nullsafe/models.ml b/infer/src/nullsafe/models.ml index 06d9c069c..dfb4e98f5 100644 --- a/infer/src/nullsafe/models.ml +++ b/infer/src/nullsafe/models.ml @@ -27,27 +27,6 @@ let table_has_procedure table proc_name = with Caml.Not_found -> false -(* This is used outside of nullsafe for biabduction. - If biabduction and nullsafe want to depend on common functionality, this functionality - should be refactored out in a dedicated library. - *) -let get_modelled_annotated_signature_for_biabduction proc_attributes = - let proc_name = proc_attributes.ProcAttributes.proc_name in - let annotated_signature = - AnnotatedSignature.get ~is_callee_in_trust_list:false ~nullsafe_mode:NullsafeMode.Default - proc_attributes - in - let proc_id = Procname.to_unique_id proc_name in - let lookup_models_nullable ann_sig = - try - let modelled_nullability = Hashtbl.find annotated_table_nullability proc_id in - AnnotatedSignature.set_modelled_nullability proc_name ann_sig InternalModel - modelled_nullability - with Caml.Not_found -> ann_sig - in - annotated_signature |> lookup_models_nullable - - let get_unique_repr proc_name = let java_proc_name = match proc_name with Procname.Java java_proc_name -> Some java_proc_name | _ -> None