diff --git a/infer/src/IR/SourceFiles.ml b/infer/src/IR/SourceFiles.ml index 0b12503a0..54ff15c1e 100644 --- a/infer/src/IR/SourceFiles.ml +++ b/infer/src/IR/SourceFiles.ml @@ -165,3 +165,14 @@ let pp_all ~filter ~type_environment ~procedure_names ~freshly_captured fmt () = ~log:"printing all source files") in F.fprintf fmt "@[%a@]" pp_result stmt ) + + +let get_procs_in_file proc_name = + let source_file = + match Attributes.load proc_name with + | Some {ProcAttributes.translation_unit} -> + Some translation_unit + | None -> + None + in + Option.value_map source_file ~default:[] ~f:proc_names_of_source diff --git a/infer/src/IR/SourceFiles.mli b/infer/src/IR/SourceFiles.mli index 209a1bdfa..f72d32f27 100644 --- a/infer/src/IR/SourceFiles.mli +++ b/infer/src/IR/SourceFiles.mli @@ -16,6 +16,9 @@ val get_all : filter:Filtering.source_files_filter -> unit -> SourceFile.t list val proc_names_of_source : SourceFile.t -> Procname.t list (** list of all the proc names (declared and defined) found in a source file *) +val get_procs_in_file : Procname.t -> Procname.t list +(** return the list of procedures in the file where the given procedure name was defined *) + val is_empty : unit -> bool (** whether there exists at least one captured source file *) diff --git a/infer/src/backend/callbacks.ml b/infer/src/backend/callbacks.ml index da057ae19..791a4d60b 100644 --- a/infer/src/backend/callbacks.ml +++ b/infer/src/backend/callbacks.ml @@ -7,8 +7,7 @@ open! IStd -type proc_callback_args = - {get_procs_in_file: Procname.t -> Procname.t list; summary: Summary.t; exe_env: Exe_env.t} +type proc_callback_args = {summary: Summary.t; exe_env: Exe_env.t} type proc_callback_t = proc_callback_args -> Summary.t @@ -47,16 +46,6 @@ let iterate_procedure_callbacks exe_env summary = let proc_name = Procdesc.get_proc_name proc_desc in let procedure_language = Procname.get_language proc_name in Language.curr_language := procedure_language ; - let get_procs_in_file proc_name = - let source_file = - match Attributes.load proc_name with - | Some {ProcAttributes.translation_unit} -> - Some translation_unit - | None -> - None - in - Option.value_map source_file ~default:[] ~f:SourceFiles.proc_names_of_source - in let is_specialized = Procdesc.is_specialized proc_desc in List.fold_right ~init:summary !procedure_callbacks_rev ~f:(fun {checker_name; dynamic_dispatch; language; callback} summary -> @@ -66,7 +55,7 @@ let iterate_procedure_callbacks exe_env summary = log_begin_event logger ~name:checker_name ~categories:["backend"] ~arguments:[("proc", `String (Procname.to_string proc_name))] () )) ; - let summary = callback {get_procs_in_file; summary; exe_env} in + let summary = callback {summary; exe_env} in PerfEvent.(log (fun logger -> log_end_event logger ())) ; summary ) else summary ) diff --git a/infer/src/backend/callbacks.mli b/infer/src/backend/callbacks.mli index 81dc3d362..07e153b52 100644 --- a/infer/src/backend/callbacks.mli +++ b/infer/src/backend/callbacks.mli @@ -27,8 +27,7 @@ open! IStd - get_proc_desc to get a proc desc from a proc name - Type environment. - Procedure for the callback to act on. *) -type proc_callback_args = - {get_procs_in_file: Procname.t -> Procname.t list; summary: Summary.t; exe_env: Exe_env.t} +type proc_callback_args = {summary: Summary.t; exe_env: Exe_env.t} (* Result is updated summary with all information relevant for the checker (including list of errors found by the checker for this procedure *) type proc_callback_t = proc_callback_args -> Summary.t diff --git a/infer/src/checkers/Siof.ml b/infer/src/checkers/Siof.ml index 4b3d57ae4..e4fa289c9 100644 --- a/infer/src/checkers/Siof.ml +++ b/infer/src/checkers/Siof.ml @@ -267,7 +267,7 @@ let siof_check gname (summary : Summary.t) = () -let checker {Callbacks.exe_env; summary; get_procs_in_file} : Summary.t = +let checker {Callbacks.exe_env; summary} : Summary.t = let proc_desc = Summary.get_proc_desc summary in let pname = Procdesc.get_proc_name proc_desc in let tenv = Exe_env.get_tenv exe_env pname in @@ -282,7 +282,7 @@ let checker {Callbacks.exe_env; summary; get_procs_in_file} : Summary.t = "__infer_translation_unit_init_streams") |> Pvar.get_initializer_pname ) in - get_procs_in_file pname |> List.exists ~f:(Procname.equal magic_iostream_marker) + SourceFiles.get_procs_in_file pname |> List.exists ~f:(Procname.equal magic_iostream_marker) in includes_iostream (Procdesc.get_attributes proc_desc).ProcAttributes.translation_unit in diff --git a/infer/src/nullsafe/Initializers.ml b/infer/src/nullsafe/Initializers.ml index a7a2e6328..76b1c0b26 100644 --- a/infer/src/nullsafe/Initializers.ml +++ b/infer/src/nullsafe/Initializers.ml @@ -79,7 +79,7 @@ let final_typestates initializers_current_class tenv typecheck_proc = List.rev !final_typestates -let pname_and_pdescs_with tenv curr_pname get_procs_in_file f = +let pname_and_pdescs_with tenv curr_pname f = let res = ref [] in let filter pname = match PatternMatch.lookup_attributes tenv pname with @@ -96,7 +96,7 @@ let pname_and_pdescs_with tenv curr_pname get_procs_in_file f = | None -> () in - List.iter ~f:do_proc (get_procs_in_file curr_pname) ; + List.iter ~f:do_proc (SourceFiles.get_procs_in_file curr_pname) ; List.rev !res @@ -105,7 +105,7 @@ let get_class pn = (** Typestates after the current procedure and all initializer procedures. *) -let final_initializer_typestates_lazy tenv curr_pname curr_pdesc get_procs_in_file typecheck_proc = +let final_initializer_typestates_lazy tenv curr_pname curr_pdesc typecheck_proc = lazy (let is_initializer proc_attributes = PatternMatch.method_is_initializer tenv proc_attributes @@ -120,7 +120,7 @@ let final_initializer_typestates_lazy tenv curr_pname curr_pdesc get_procs_in_fi Annotations.ia_is_initializer ia in let initializers_current_class = - pname_and_pdescs_with tenv curr_pname get_procs_in_file (function pname, proc_attributes -> + pname_and_pdescs_with tenv curr_pname (function pname, proc_attributes -> is_initializer proc_attributes && equal_class_opt (get_class pname) (get_class curr_pname) ) in @@ -129,10 +129,10 @@ let final_initializer_typestates_lazy tenv curr_pname curr_pdesc get_procs_in_fi (** Typestates after all constructors. *) -let final_constructor_typestates_lazy tenv curr_pname get_procs_in_file typecheck_proc = +let final_constructor_typestates_lazy tenv curr_pname typecheck_proc = lazy (let constructors_current_class = - pname_and_pdescs_with tenv curr_pname get_procs_in_file (fun (pname, _) -> + pname_and_pdescs_with tenv curr_pname (fun (pname, _) -> Procname.is_constructor pname && equal_class_opt (get_class pname) (get_class curr_pname) ) in diff --git a/infer/src/nullsafe/Initializers.mli b/infer/src/nullsafe/Initializers.mli index 5f148f814..f7300f00c 100644 --- a/infer/src/nullsafe/Initializers.mli +++ b/infer/src/nullsafe/Initializers.mli @@ -22,7 +22,6 @@ val final_initializer_typestates_lazy : Tenv.t -> Procname.t -> Procdesc.t - -> (Procname.t -> Procname.t list) -> (bool -> Procname.t -> Procdesc.t -> 'a option -> 'b * 'c option) -> (Procname.t * 'c) list lazy_t (** Typestates after the current constructor and all initializer procedures. *) @@ -30,7 +29,6 @@ val final_initializer_typestates_lazy : val final_constructor_typestates_lazy : Tenv.t -> Procname.t - -> (Procname.t -> Procname.t list) -> (bool -> Procname.t -> Procdesc.t -> 'a option -> 'b * 'c option) -> (Procname.t * 'c) list lazy_t (** Typestates after all constructors. *) diff --git a/infer/src/nullsafe/eradicate.ml b/infer/src/nullsafe/eradicate.ml index 34bf3c08c..fb719cbb8 100644 --- a/infer/src/nullsafe/eradicate.ml +++ b/infer/src/nullsafe/eradicate.ml @@ -106,8 +106,8 @@ let callback1 tenv find_canonical_duplicate calls_this checks idenv curr_pname c (!calls_this, None) -let analyze_procedure tenv proc_name proc_desc calls_this checks Callbacks.{get_procs_in_file} - annotated_signature linereader proc_loc : unit = +let analyze_procedure tenv proc_name proc_desc calls_this checks annotated_signature linereader + proc_loc : unit = let idenv = Idenv.create proc_desc in let find_duplicate_nodes = State.mk_find_duplicate_nodes proc_desc in let find_canonical_duplicate node = @@ -152,12 +152,10 @@ let analyze_procedure tenv proc_name proc_desc calls_this checks Callbacks.{get_ && checks.TypeCheck.eradicate then ( let typestates_for_curr_constructor_and_all_initializer_methods = - Initializers.final_initializer_typestates_lazy tenv proc_name proc_desc get_procs_in_file - typecheck_proc + Initializers.final_initializer_typestates_lazy tenv proc_name proc_desc typecheck_proc in let typestates_for_all_constructors_incl_current = - Initializers.final_constructor_typestates_lazy tenv proc_name get_procs_in_file - typecheck_proc + Initializers.final_constructor_typestates_lazy tenv proc_name typecheck_proc in EradicateChecks.check_constructor_initialization tenv find_canonical_duplicate proc_name proc_desc start_node ~nullsafe_mode:annotated_signature.AnnotatedSignature.nullsafe_mode @@ -195,7 +193,7 @@ let find_reason_to_skip_analysis proc_name proc_desc = (** Entry point for the nullsafe procedure-level analysis. *) -let callback checks ({Callbacks.summary} as callback_args) : Summary.t = +let callback checks {Callbacks.summary; exe_env} : Summary.t = let proc_desc = Summary.get_proc_desc summary in let proc_name = Procdesc.get_proc_name proc_desc in L.debug Analysis Medium "Analysis of %a@\n" Procname.pp proc_name ; @@ -206,7 +204,7 @@ let callback checks ({Callbacks.summary} as callback_args) : Summary.t = | None -> (* start the analysis! *) let calls_this = ref false in - let tenv = Exe_env.get_tenv callback_args.exe_env proc_name in + let tenv = Exe_env.get_tenv exe_env proc_name in let annotated_signature = AnnotatedSignature.get_for_class_under_analysis tenv (Procdesc.get_attributes proc_desc) in @@ -219,8 +217,8 @@ let callback checks ({Callbacks.summary} as callback_args) : Summary.t = (* The main method - during this the actual analysis will happen and TypeErr will be populated with issues (and some of them - reported). *) - analyze_procedure tenv proc_name proc_desc calls_this checks callback_args annotated_signature - linereader loc ; + analyze_procedure tenv proc_name proc_desc calls_this checks annotated_signature linereader + loc ; (* Collect issues that were detected during analysis and put them in summary for further processing *) let issues = TypeErr.get_errors () |> List.map ~f:(fun (issues, _) -> issues) in (* Report errors of "farall" class - those could not be reported during analysis phase. *)