From 32d462b778ae8ce2016899089e432e30e0174263 Mon Sep 17 00:00:00 2001 From: Jeremy Dubreil Date: Wed, 30 Aug 2017 13:19:12 -0700 Subject: [PATCH] [infer][java] add an option to only translate the signature of the methods and skip the body Summary: This adds an option to only translate the body of a method when the file matches the give pattern. This is especially intended to be use for generated files. Reviewed By: jvillard Differential Revision: D5729120 fbshipit-source-id: 1e28469 --- .inferconfig | 7 +++++ infer/src/backend/inferconfig.ml | 3 +++ infer/src/backend/inferconfig.mli | 2 ++ infer/src/base/Config.ml | 19 +++++++++++--- infer/src/base/Config.mli | 2 ++ infer/src/java/jFrontend.ml | 3 +++ infer/tests/build_systems/buck/issues.exp | 1 + .../tests/build_systems/genrule/module1/BUCK | 2 +- .../module1/SkipImplementationClass1.java | 26 +++++++++++++++++++ .../tests/build_systems/genrule/module2/BUCK | 2 +- .../build_systems/genrule/module2/Class2.java | 11 ++++++++ 11 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 infer/tests/build_systems/genrule/module1/SkipImplementationClass1.java diff --git a/.inferconfig b/.inferconfig index f203abe48..b4e598b9e 100644 --- a/.inferconfig +++ b/.inferconfig @@ -6,5 +6,12 @@ "language": "Java", "source_contains": "_SHOULD_BE_SKIPPED_" } + ], + "skip-implementation": [ + { + "language": "Java", + "source_contains": "_SHOULD_SKIP_IMPLEMENTATION_" + } ] + } diff --git a/infer/src/backend/inferconfig.ml b/infer/src/backend/inferconfig.ml index 6aa6a11bf..db67c81ee 100644 --- a/infer/src/backend/inferconfig.ml +++ b/infer/src/backend/inferconfig.ml @@ -296,6 +296,9 @@ let never_return_null_matcher = let skip_translation_matcher = FileOrProcMatcher.load_matcher (patterns_of_json_with_key Config.patterns_skip_translation) +let skip_implementation_matcher = + FileOrProcMatcher.load_matcher (patterns_of_json_with_key Config.patterns_skip_implementation) + let load_filters analyzer = { whitelist= Config.analysis_path_regex_whitelist analyzer ; blacklist= Config.analysis_path_regex_blacklist analyzer diff --git a/infer/src/backend/inferconfig.mli b/infer/src/backend/inferconfig.mli index a13c22f3b..d3424e731 100644 --- a/infer/src/backend/inferconfig.mli +++ b/infer/src/backend/inferconfig.mli @@ -30,6 +30,8 @@ val never_return_null_matcher : SourceFile.t -> Typ.Procname.t -> bool val skip_translation_matcher : SourceFile.t -> Typ.Procname.t -> bool +val skip_implementation_matcher : SourceFile.t -> Typ.Procname.t -> bool + val modeled_expensive_matcher : (string -> bool) -> Typ.Procname.t -> bool val test : unit -> unit diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index fa26058a4..fba97cff8 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -1338,6 +1338,13 @@ and patterns_never_returning_null = , CLOpt.mk_json ~deprecated:["never_returning_null"] ~long "Matcher or list of matchers for functions that never return $(i,null)." ) +and patterns_skip_implementation = + let long = "skip-implementation" in + ( long + , CLOpt.mk_json ~long + "Matcher or list of matchers for names of files where we only want to translate the method declaration, skipping the body of the methods (Java only)." + ) + and patterns_skip_translation = let long = "skip-translation" in ( long @@ -2131,16 +2138,20 @@ and only_show = !only_show and passthroughs = !passthroughs +and patterns_modeled_expensive = + match patterns_modeled_expensive + with k, r -> (k, !r) + and patterns_never_returning_null = match patterns_never_returning_null with k, r -> (k, !r) -and patterns_skip_translation = - match patterns_skip_translation +and patterns_skip_implementation = + match patterns_skip_implementation with k, r -> (k, !r) -and patterns_modeled_expensive = - match patterns_modeled_expensive +and patterns_skip_translation = + match patterns_skip_translation with k, r -> (k, !r) and per_procedure_parallelism = !per_procedure_parallelism diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index a1cad9f90..91344f330 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -185,6 +185,8 @@ val patterns_modeled_expensive : string * Yojson.Basic.json val patterns_never_returning_null : string * Yojson.Basic.json +val patterns_skip_implementation : string * Yojson.Basic.json + val patterns_skip_translation : string * Yojson.Basic.json val per_procedure_parallelism : bool diff --git a/infer/src/java/jFrontend.ml b/infer/src/java/jFrontend.ml index 9955578ea..cf92d4e3f 100644 --- a/infer/src/java/jFrontend.ml +++ b/infer/src/java/jFrontend.ml @@ -157,6 +157,9 @@ let create_icfg source_file linereader program icfg cn node = -> ignore (JTrans.create_am_procdesc source_file program icfg am proc_name) | Javalib.ConcreteMethod cm when JTrans.is_java_native cm -> ignore (JTrans.create_native_procdesc source_file program icfg cm proc_name) + | Javalib.ConcreteMethod cm + when Inferconfig.skip_implementation_matcher source_file proc_name + -> ignore (JTrans.create_native_procdesc source_file program icfg cm proc_name) | Javalib.ConcreteMethod cm -> add_cmethod source_file program linereader icfg cm proc_name ) ; Cg.add_defined_node icfg.JContext.cg proc_name diff --git a/infer/tests/build_systems/buck/issues.exp b/infer/tests/build_systems/buck/issues.exp index f257c1d0d..73930f00b 100644 --- a/infer/tests/build_systems/buck/issues.exp +++ b/infer/tests/build_systems/buck/issues.exp @@ -1,4 +1,5 @@ infer/tests/build_systems/genrule/module1/Class1.java, void Class1.localNPE1(), 2, NULL_DEREFERENCE, [start of procedure localNPE1()] +infer/tests/build_systems/genrule/module2/Class2.java, void Class2.followMethodDeclarationOnlyBad(SkipImplementationClass1), 2, NULL_DEREFERENCE, [start of procedure followMethodDeclarationOnlyBad(...),Skipping annotatedNullable(): function or method not found] infer/tests/build_systems/genrule/module2/Class2.java, void Class2.interTargetAbstractNPE(Class1), 2, NULL_DEREFERENCE, [start of procedure interTargetAbstractNPE(...),Skipping abstractMayReturnNull(): function or method not found] infer/tests/build_systems/genrule/module2/Class2.java, void Class2.interTargetNPE(), 2, NULL_DEREFERENCE, [start of procedure interTargetNPE(),start of procedure returnsNull(),return from a call to String Class1.returnsNull()] infer/tests/build_systems/genrule/module2/Class2.java, void Class2.interTargetNativeNPE(Class1), 2, NULL_DEREFERENCE, [start of procedure interTargetNativeNPE(...),Skipping nativeMayReturnNull(): function or method not found] diff --git a/infer/tests/build_systems/genrule/module1/BUCK b/infer/tests/build_systems/genrule/module1/BUCK index 7009d9de4..d39b12ca6 100644 --- a/infer/tests/build_systems/genrule/module1/BUCK +++ b/infer/tests/build_systems/genrule/module1/BUCK @@ -1,6 +1,6 @@ java_library( name='module1', - srcs=['Class1.java'], + srcs=glob(["*.java"]), deps=[ '//infer/tests/build_systems/genrule/annotations:annotations', ], diff --git a/infer/tests/build_systems/genrule/module1/SkipImplementationClass1.java b/infer/tests/build_systems/genrule/module1/SkipImplementationClass1.java new file mode 100644 index 000000000..fa0c030e4 --- /dev/null +++ b/infer/tests/build_systems/genrule/module1/SkipImplementationClass1.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2017 - 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_SKIP_IMPLEMENTATION_ + +package genrule.module1; + +import genrule.annotations.Nullable; + +public class SkipImplementationClass1 { + + public @Nullable Object annotatedNullable() { + return new Object(); + } + + public Object notAnnotatedNullable() { + return null; + } + +} diff --git a/infer/tests/build_systems/genrule/module2/BUCK b/infer/tests/build_systems/genrule/module2/BUCK index 48c768eb9..79218845f 100644 --- a/infer/tests/build_systems/genrule/module2/BUCK +++ b/infer/tests/build_systems/genrule/module2/BUCK @@ -1,6 +1,6 @@ java_library( name='module2', - srcs=['Class2.java'], + srcs=glob(["*.java"]), deps=[ '//infer/tests/build_systems/genrule/module1:module1' ] diff --git a/infer/tests/build_systems/genrule/module2/Class2.java b/infer/tests/build_systems/genrule/module2/Class2.java index a15c64311..3c8433ef9 100644 --- a/infer/tests/build_systems/genrule/module2/Class2.java +++ b/infer/tests/build_systems/genrule/module2/Class2.java @@ -10,6 +10,7 @@ package genrule.module2; import genrule.module1.Class1; +import genrule.module1.SkipImplementationClass1; public class Class2 { @@ -33,4 +34,14 @@ public class Class2 { obj.toString(); } + void followMethodDeclarationOnlyBad(SkipImplementationClass1 obj1) { + Object obj2 = obj1.annotatedNullable(); + obj2.toString(); + } + + void followMethodDeclarationOnlyOk(SkipImplementationClass1 obj1) { + Object obj2 = obj1.notAnnotatedNullable(); + obj2.toString(); + } + }