From 6f3873aa993bfac5f6f05e4cf179ae01c21ce17b Mon Sep 17 00:00:00 2001 From: jrm Date: Wed, 28 Oct 2015 09:37:56 -0700 Subject: [PATCH] Adding inferconfig support to skip the translation of generated source code Summary: public This allow to tell Infer to skip the translation of some files. This is especially useful to skip the translation of some generated files following the syntax: > cat .inferconfig { "skip_translation": [ { "language": "Java", "source_contains": "_SHOULD_BE_SKIPPED_" } ] } Reviewed By: cristianoc Differential Revision: D2588095 fb-gh-sync-id: 3fda816 --- examples/android_hello/.inferconfig | 1 + .../infer/inferandroidexample/Generated.java | 20 ++++++++++++++++++ .../inferandroidexample/MainActivity.java | 15 +++++++++++++ examples/android_hello/gradle_report.json | 4 ++-- infer/src/backend/inferconfig.ml | 7 +++++++ infer/src/backend/inferconfig.mli | 5 +++++ infer/src/backend/procname.ml | 4 ++++ infer/src/backend/procname.mli | 2 ++ infer/src/java/jMain.ml | 14 ++++++++++--- infer/tests/.inferconfig | 1 + infer/tests/codetoanalyze/java/.inferconfig | 6 ++++++ .../java/infer/NullPointerExceptions.java | 5 +++++ .../java/infer/SkippedSourceFile.java | 21 +++++++++++++++++++ 13 files changed, 100 insertions(+), 5 deletions(-) create mode 120000 examples/android_hello/.inferconfig create mode 100644 examples/android_hello/app/src/main/java/infer/inferandroidexample/Generated.java create mode 120000 infer/tests/.inferconfig create mode 100644 infer/tests/codetoanalyze/java/infer/SkippedSourceFile.java diff --git a/examples/android_hello/.inferconfig b/examples/android_hello/.inferconfig new file mode 120000 index 000000000..261f54568 --- /dev/null +++ b/examples/android_hello/.inferconfig @@ -0,0 +1 @@ +/Users/jrm/infer/.inferconfig \ No newline at end of file diff --git a/examples/android_hello/app/src/main/java/infer/inferandroidexample/Generated.java b/examples/android_hello/app/src/main/java/infer/inferandroidexample/Generated.java new file mode 100644 index 000000000..3bce0d8ab --- /dev/null +++ b/examples/android_hello/app/src/main/java/infer/inferandroidexample/Generated.java @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2015 - present Facebook, Inc. +* All rights reserved. +* +* This source code is licensed under the BSD style license found in the +* LICENSE file in the root directory of this source tree. An additional grant +* of patent rights can be found in the PATENTS file in the same directory. +*/ + +// _SHOULD_BE_SKIPPED_ + +package infer.inferandroidexample; + +public class Generated { + + static Object returnsNull() { + return null; + } + +} diff --git a/examples/android_hello/app/src/main/java/infer/inferandroidexample/MainActivity.java b/examples/android_hello/app/src/main/java/infer/inferandroidexample/MainActivity.java index 4e1e87073..26330699b 100644 --- a/examples/android_hello/app/src/main/java/infer/inferandroidexample/MainActivity.java +++ b/examples/android_hello/app/src/main/java/infer/inferandroidexample/MainActivity.java @@ -1,3 +1,12 @@ +/* +* Copyright (c) 2015 - present Facebook, Inc. +* All rights reserved. +* +* This source code is licensed under the BSD style license found in the +* LICENSE file in the root directory of this source tree. An additional grant +* of patent rights can be found in the PATENTS file in the same directory. +*/ + package infer.inferandroidexample; import android.support.v7.app.ActionBarActivity; @@ -60,4 +69,10 @@ public class MainActivity extends ActionBarActivity { return super.onOptionsItemSelected(item); } + + private void inferShouldNotReport() { + Object o = Generated.returnsNull(); + o.toString(); + } + } diff --git a/examples/android_hello/gradle_report.json b/examples/android_hello/gradle_report.json index 74dfb8151..d9e69f9bb 100644 --- a/examples/android_hello/gradle_report.json +++ b/examples/android_hello/gradle_report.json @@ -1,13 +1,13 @@ [ { "file": "app/src/main/java/infer/inferandroidexample/MainActivity.java", - "line": "20", + "line": "29", "type": "NULL_DEREFERENCE", "procedure": "void MainActivity.onCreate(Bundle)" }, { "file": "app/src/main/java/infer/inferandroidexample/MainActivity.java", - "line": "37", + "line": "46", "type": "RESOURCE_LEAK", "procedure": "void MainActivity.writeToFile()" } diff --git a/infer/src/backend/inferconfig.ml b/infer/src/backend/inferconfig.ml index 6700af39f..ff1f428ae 100644 --- a/infer/src/backend/inferconfig.ml +++ b/infer/src/backend/inferconfig.ml @@ -271,6 +271,7 @@ struct end (* of module FileOrProcMatcher *) + module NeverReturnNull = FileOrProcMatcher(struct let json_key = "never_returning_null" end) @@ -279,6 +280,11 @@ module ProcMatcher = FileOrProcMatcher(struct let json_key = "suppress_procedures" end) +module SkipTranslationMatcher = FileOrProcMatcher(struct + let json_key = "skip_translation" + end) + + let inferconfig () = match !inferconfig_home with | Some dir -> Filename.concat dir inferconfig_file | None -> inferconfig_file @@ -311,6 +317,7 @@ let make_proc_filter_from_local_config () = | None -> ProcMatcher.default_matcher in fun pname -> not (filter DB.source_file_empty pname) + let filters_from_inferconfig inferconfig : filters = let path_filter = let whitelist_filter : path_filter = diff --git a/infer/src/backend/inferconfig.mli b/infer/src/backend/inferconfig.mli index 29dd96b4f..4b4adc206 100644 --- a/infer/src/backend/inferconfig.mli +++ b/infer/src/backend/inferconfig.mli @@ -41,5 +41,10 @@ module NeverReturnNull : sig val load_matcher : string -> matcher end +module SkipTranslationMatcher : sig + type matcher = DB.source_file -> Procname.t -> bool + val load_matcher : string -> matcher +end + (** Load the config file and list the files to report on *) val test: unit -> unit diff --git a/infer/src/backend/procname.ml b/infer/src/backend/procname.ml index f7102a853..a7d0f46cb 100644 --- a/infer/src/backend/procname.ml +++ b/infer/src/backend/procname.ml @@ -63,6 +63,10 @@ type detail_level = | NON_VERBOSE | SIMPLE + +let empty = OBJC_BLOCK "" + + let is_verbose v = match v with | VERBOSE -> true diff --git a/infer/src/backend/procname.mli b/infer/src/backend/procname.mli index 5445919cb..14ad4396d 100644 --- a/infer/src/backend/procname.mli +++ b/infer/src/backend/procname.mli @@ -25,6 +25,8 @@ type objc_method_kind = | Instance_objc_method (* for instance methods in ObjC *) | Class_objc_method (* for class methods in ObjC *) +val empty : t + (** Mangled string for method types *) val mangled_of_objc_method_kind : objc_method_kind -> string option diff --git a/infer/src/java/jMain.ml b/infer/src/java/jMain.ml index 87468d022..04a4e24d0 100644 --- a/infer/src/java/jMain.ml +++ b/infer/src/java/jMain.ml @@ -81,7 +81,6 @@ let do_source_file never_null_matcher linereader classes program tenv source_basename source_file proc_file_map = JUtils.log "\nfilename: %s (%s)@." (DB.source_file_to_string source_file) source_basename; - init_global_state source_file; let call_graph, cfg = JFrontend.compute_source_icfg never_null_matcher linereader classes program tenv source_basename source_file in @@ -145,10 +144,19 @@ let do_all_files classpath sources classes = let program = JClasspath.load_program classpath classes sources in let tenv = load_tenv program in let linereader = Printer.LineReader.create () in - let never_null_matcher = Inferconfig.NeverReturnNull.load_matcher (Inferconfig.inferconfig ()) in + let skip_translation_matcher = + Inferconfig.SkipTranslationMatcher.load_matcher (Inferconfig.inferconfig ()) in + let never_null_matcher = + Inferconfig.NeverReturnNull.load_matcher (Inferconfig.inferconfig ()) in let proc_file_map = + let skip filename = + skip_translation_matcher filename Procname.empty in StringMap.fold - (do_source_file never_null_matcher linereader classes program tenv) + (fun basename source_file map -> + init_global_state source_file; + if skip source_file then map + else do_source_file + never_null_matcher linereader classes program tenv basename source_file map) sources Procname.Map.empty in if !JConfig.dependency_mode then diff --git a/infer/tests/.inferconfig b/infer/tests/.inferconfig new file mode 120000 index 000000000..4d320b9d1 --- /dev/null +++ b/infer/tests/.inferconfig @@ -0,0 +1 @@ +../../.inferconfig \ No newline at end of file diff --git a/infer/tests/codetoanalyze/java/.inferconfig b/infer/tests/codetoanalyze/java/.inferconfig index f5e679a23..04d35658b 100644 --- a/infer/tests/codetoanalyze/java/.inferconfig +++ b/infer/tests/codetoanalyze/java/.inferconfig @@ -12,5 +12,11 @@ ], "infer_blacklist_files_containing": [ "@generated" + ], + "skip_translation": [ + { + "language": "Java", + "source_contains": "_SHOULD_BE_SKIPPED_" + } ] } diff --git a/infer/tests/codetoanalyze/java/infer/NullPointerExceptions.java b/infer/tests/codetoanalyze/java/infer/NullPointerExceptions.java index 9789765fe..71a05c679 100644 --- a/infer/tests/codetoanalyze/java/infer/NullPointerExceptions.java +++ b/infer/tests/codetoanalyze/java/infer/NullPointerExceptions.java @@ -425,4 +425,9 @@ public class NullPointerExceptions { o.toString(); } + void shouldNotReportOnSkippedSource() { + Object o = SkippedSourceFile.createdBySkippedFile(); + o.toString(); + } + } diff --git a/infer/tests/codetoanalyze/java/infer/SkippedSourceFile.java b/infer/tests/codetoanalyze/java/infer/SkippedSourceFile.java new file mode 100644 index 000000000..0f5355033 --- /dev/null +++ b/infer/tests/codetoanalyze/java/infer/SkippedSourceFile.java @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2015 - present Facebook, Inc. +* All rights reserved. +* +* This source code is licensed under the BSD style license found in the +* LICENSE file in the root directory of this source tree. An additional grant +* of patent rights can be found in the PATENTS file in the same directory. +*/ + +// _SHOULD_BE_SKIPPED_ + +package codetoanalyze.java.infer; + + +public class SkippedSourceFile { + + static Object createdBySkippedFile() { + return null; + } + +}