diff --git a/infer/lib/python/infer b/infer/lib/python/infer index 1bb87f0ee..f4569af8c 100755 --- a/infer/lib/python/infer +++ b/infer/lib/python/infer @@ -114,6 +114,7 @@ def main(): remove_infer_out = (imported_module and not args.incremental + and not args.reactive and capture_module_name != 'analyze' and not args.buck) if remove_infer_out: diff --git a/infer/lib/python/inferlib/analyze.py b/infer/lib/python/inferlib/analyze.py index cb11444f0..63e6dc5d8 100644 --- a/infer/lib/python/inferlib/analyze.py +++ b/infer/lib/python/inferlib/analyze.py @@ -75,6 +75,9 @@ base_group.add_argument('-ic', '--changed-only', action=ConfirmIncrementalAction, help='''Same as -i, but does not analyze dependencies of changed procedures.''') +base_group.add_argument('--reactive', action='store_true', + help='''Analyze in reactive propagation mode + starting from changed files.''') base_group.add_argument('--debug-exceptions', action='store_true', help='''Generate lightweight debugging information: just print the internal exceptions during analysis''') @@ -418,6 +421,9 @@ class Infer: else: infer_options.append('-incremental') + if self.args.reactive: + infer_options.append('-reactive') + if self.args.specs_dirs: infer_options += self.args.specs_dirs diff --git a/infer/src/backend/clusterMakefile.ml b/infer/src/backend/clusterMakefile.ml index 3fd52aeb1..2c3e09dc1 100644 --- a/infer/src/backend/clusterMakefile.ml +++ b/infer/src/backend/clusterMakefile.ml @@ -30,12 +30,29 @@ let pp_prolog fmt clusters = begin match Cluster.get_ondemand_info ce with | Some source_dir -> - let in_ondemand_config = match Ondemand.read_dirs_to_analyze () with + let fname = DB.source_dir_to_string source_dir in + let in_ondemand_config = + match Ondemand.read_dirs_to_analyze () with | None -> - true + None | Some set -> - StringSet.mem (DB.source_dir_to_string source_dir) set in - in_ondemand_config + Some (StringSet.mem fname set) in + let check_modified () = + let modified = + DB.file_was_updated_after_start (DB.filename_from_string fname) in + if modified && + !Config.developer_mode + then L.stdout "Modified: %s@." fname; + modified in + begin + match in_ondemand_config with + | Some b -> (* ondemand config file is specified *) + b + | None when !Config.reactive_mode -> + check_modified () + | None -> + true + end | None -> true end diff --git a/infer/src/backend/config.ml b/infer/src/backend/config.ml index 6ceed0dd4..987389734 100644 --- a/infer/src/backend/config.ml +++ b/infer/src/backend/config.ml @@ -179,9 +179,14 @@ let eradicate = ref false (** should the checkers be run? *) let checkers_enabled () = not !eradicate -(** flag to activate ondemand mode. *) +(** flag for ondemand mode: + procedure calls trigger a new analysis if the summary is not present already *) let ondemand_enabled = ref false +(** flag for reactive mode: + the analysis starts from the files captured since the "infer" command started *) +let reactive_mode = ref false + (** Flag for footprint discovery mode *) let footprint = ref true diff --git a/infer/src/backend/inferanalyze.ml b/infer/src/backend/inferanalyze.ml index bcedeb4e6..0f68c3342 100644 --- a/infer/src/backend/inferanalyze.ml +++ b/infer/src/backend/inferanalyze.ml @@ -177,6 +177,11 @@ let arg_desc = None, "print the builtin functions and exit" ; + "-reactive", + Arg.Unit (fun () -> Config.ondemand_enabled := true; Config.reactive_mode := true), + None, + "analyze in reactive propagation mode starting from changed files" + ; "-source_path", Arg.String source_path, Some "path",