From 43daa760ee4c1b7bd56df8189556fb55748f795c Mon Sep 17 00:00:00 2001 From: Sam Blackshear Date: Wed, 13 Jan 2016 09:51:01 -0800 Subject: [PATCH] adding InferJava flags for classpath and class-source map, along with associated Python boilerplate Reviewed By: cristianoc Differential Revision: D2822910 fb-gh-sync-id: c28b192 --- infer/lib/python/inferlib/analyze.py | 26 +++++++++++++++++++ infer/lib/python/inferlib/config.py | 2 ++ infer/lib/python/inferlib/jwlib.py | 10 +++++++ infer/src/java/jConfig.ml | 4 +++ infer/src/java/jMain.ml | 2 ++ .../incremental/changed_only_mode/Child.java | 2 +- .../java/incremental/child_changed/Child.java | 2 +- 7 files changed, 46 insertions(+), 2 deletions(-) diff --git a/infer/lib/python/inferlib/analyze.py b/infer/lib/python/inferlib/analyze.py index ba7c4b31a..ae53ea903 100644 --- a/infer/lib/python/inferlib/analyze.py +++ b/infer/lib/python/inferlib/analyze.py @@ -298,9 +298,35 @@ class Infer: shutil.rmtree(self.args.infer_out) exit(os.EX_OK) + # create a classpath to pass to the frontend + def create_frontend_classpath(self): + classes_out = '.' + if self.javac.args.classes_out is not None: + classes_out = self.javac.args.classes_out + classes_out = os.path.abspath(classes_out) + original_classpath = [] + if self.javac.args.bootclasspath is not None: + original_classpath = self.javac.args.bootclasspath.split(':') + if self.javac.args.classpath is not None: + original_classpath += self.javac.args.classpath.split(':') + if len(original_classpath) > 0: + # add classes_out, unless it's already in the classpath + classpath = [os.path.abspath(p) for p in original_classpath] + if not classes_out in classpath: + classpath = [classes_out] + classpath + # remove models.jar; it's added by the frontend + models_jar = os.path.abspath(config.MODELS_JAR) + if models_jar in classpath: + classpath.remove(models_jar) + return ':'.join(classpath) + return classes_out + + def run_infer_frontend(self): infer_cmd = [utils.get_cmd_in_bin_dir('InferJava')] + infer_cmd += ['-classpath', self.create_frontend_classpath()] + infer_cmd += ['-class_source_map', self.javac.class_source_map] if not self.args.absolute_paths: infer_cmd += ['-project_root', self.args.project_root] diff --git a/infer/lib/python/inferlib/config.py b/infer/lib/python/inferlib/config.py index a17e1ff4a..31ceb7449 100644 --- a/infer/lib/python/inferlib/config.py +++ b/infer/lib/python/inferlib/config.py @@ -47,6 +47,8 @@ IOS_BUILD_OUTPUT = 'build_output' BUCK_INFER_OUT = 'infer' +CLASS_SOURCE_MAP_OUTPUT_FILENAME_OPTION = 'classSourceMapOutputFilename' + # exit value when infer finds something to report BUG_FOUND_ERROR_CODE = 2 diff --git a/infer/lib/python/inferlib/jwlib.py b/infer/lib/python/inferlib/jwlib.py index 229549ddb..80fbabfdf 100644 --- a/infer/lib/python/inferlib/jwlib.py +++ b/infer/lib/python/inferlib/jwlib.py @@ -71,6 +71,16 @@ class CompilerCall: javac_cmd += self.remaining_args javac_cmd.append('-J-Duser.language=en') + with tempfile.NamedTemporaryFile( + mode='w', + suffix='.json', + prefix='classSourceMap_', + delete=False) as class_source_map_out: + self.class_source_map = class_source_map_out.name + javac_cmd += ['-A%s=%s' % + (config.CLASS_SOURCE_MAP_OUTPUT_FILENAME_OPTION, + self.class_source_map)] + with tempfile.NamedTemporaryFile( mode='w', suffix='.out', diff --git a/infer/src/java/jConfig.ml b/infer/src/java/jConfig.ml index 5bbeba871..f4ab2f31a 100644 --- a/infer/src/java/jConfig.ml +++ b/infer/src/java/jConfig.ml @@ -116,6 +116,10 @@ let class_code cl = "L"^cl let errors_db_file = "errors.db" let main_errors_file = "Java_frontend.errors" +let classpath : string option ref = ref None + +let class_source_map : string option ref = ref None + (** {2 Flags } *) (* the Sawja representation of the Java Bytecode will be printed *) diff --git a/infer/src/java/jMain.ml b/infer/src/java/jMain.ml index b3b44a6b0..ebb219713 100644 --- a/infer/src/java/jMain.ml +++ b/infer/src/java/jMain.ml @@ -18,6 +18,8 @@ let arg_desc = let desc = (arg_desc_filter options_to_keep base_arg_desc) @ [ + "-classpath", Arg.String (fun classpath -> JConfig.classpath := Some classpath), None, "set the classpath"; + "-class_source_map", Arg.String (fun filename -> JConfig.class_source_map := Some filename), None, "path to class -> source map in JSON format"; "-models", Arg.String (fun filename -> JClasspath.add_models filename), Some "paths", "set the path to the jar containing the models"; "-debug", Arg.Unit (fun () -> JConfig.debug_mode := true), None, "write extra translation information"; "-dependencies", Arg.Unit (fun _ -> JConfig.dependency_mode := true), None, "translate all the dependencies during the capture"; diff --git a/infer/tests/codetoanalyze/java/incremental/changed_only_mode/Child.java b/infer/tests/codetoanalyze/java/incremental/changed_only_mode/Child.java index 27fc00098..f09b6a1f9 100644 --- a/infer/tests/codetoanalyze/java/incremental/changed_only_mode/Child.java +++ b/infer/tests/codetoanalyze/java/incremental/changed_only_mode/Child.java @@ -12,7 +12,7 @@ package codetoanalyze.java.incremental.changed_only_mode; class Child { Object bar() { - return null; + return new Object(); } Object dontReanalyze(Object o) { diff --git a/infer/tests/codetoanalyze/java/incremental/child_changed/Child.java b/infer/tests/codetoanalyze/java/incremental/child_changed/Child.java index aaf2e1fec..1fb836cf3 100644 --- a/infer/tests/codetoanalyze/java/incremental/child_changed/Child.java +++ b/infer/tests/codetoanalyze/java/incremental/child_changed/Child.java @@ -12,7 +12,7 @@ package codetoanalyze.java.incremental.child_changed; class Child { Object bar() { - return null; + return new Object(); } Object dontReanalyze(Object o) {