Summary: This replaces the previous integration written in Python, which consisted in 1) run the mvn command and parse its output to locate "directories containing source files", 2) run on files named "*.java" in these directories. This meant we had to run javac twice on each source file, and more importantly this mechanism of finding source files was very fragile. In fact, I could not make it work on several mvn projects I tried. The new integration is based on parsing "pom.xml" to add an "infer-capture" profile which instructs mvn to run `/path/to/infer` instead of `javac`. We also add this profile to each maven submodule. Users can specify an "infer-capture" profile themselves if the default one doesn't work; in that case we don't inject our own "infer-capture" profile. Reviewed By: jeremydubreil Differential Revision: D4409613 fbshipit-source-id: d664274master
parent
99e2038560
commit
2e96caac42
@ -1,87 +0,0 @@
|
||||
# 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.
|
||||
|
||||
import os
|
||||
import logging
|
||||
import re
|
||||
import util
|
||||
|
||||
from inferlib import jwlib
|
||||
|
||||
MODULE_NAME = __name__
|
||||
MODULE_DESCRIPTION = '''Run analysis of code built with a command like:
|
||||
mvn [options] [task]
|
||||
|
||||
Analysis examples:
|
||||
infer -- mvn build'''
|
||||
LANG = ['java']
|
||||
|
||||
|
||||
def gen_instance(*args):
|
||||
return MavenCapture(*args)
|
||||
|
||||
|
||||
# This creates an empty argparser for the module, which provides only
|
||||
# description/usage information and no arguments.
|
||||
create_argparser = util.base_argparser(MODULE_DESCRIPTION, MODULE_NAME)
|
||||
|
||||
|
||||
class MavenCapture:
|
||||
def __init__(self, args, cmd):
|
||||
self.args = args
|
||||
logging.info(util.run_cmd_ignore_fail(['mvn', '-version']))
|
||||
# TODO: make the extraction of targets smarter
|
||||
self.build_cmd = ['mvn', '-X'] + cmd[1:]
|
||||
|
||||
def get_infer_commands(self, verbose_output):
|
||||
file_pattern = r'\[DEBUG\] Stale source detected: ([^ ]*\.java)'
|
||||
options_pattern = '[DEBUG] Command line options:'
|
||||
source_roots_pattern = '[DEBUG] Source roots:'
|
||||
|
||||
files_to_compile = []
|
||||
calls = []
|
||||
options_next = False
|
||||
source_roots_next = False
|
||||
for line in verbose_output:
|
||||
if options_next:
|
||||
# line has format [Debug] <space separated options>
|
||||
javac_args = line.split(' ')[1:] + files_to_compile
|
||||
capture = jwlib.create_infer_command(javac_args)
|
||||
calls.append(capture)
|
||||
options_next = False
|
||||
files_to_compile = []
|
||||
|
||||
elif source_roots_next:
|
||||
# line has format [Debug] <space separated directories>
|
||||
src_roots = line.split(' ')[1:]
|
||||
for src_root in src_roots:
|
||||
for root, dirs, files in os.walk(src_root):
|
||||
for name in files:
|
||||
if name.endswith(".java"):
|
||||
path = os.path.join(root, name)
|
||||
files_to_compile.append(path)
|
||||
source_roots_next = False
|
||||
|
||||
elif options_pattern in line:
|
||||
# Next line will have javac options to run
|
||||
options_next = True
|
||||
|
||||
elif source_roots_pattern in line:
|
||||
# Next line will have directory containing files to compile
|
||||
source_roots_next = True
|
||||
|
||||
else:
|
||||
found = re.match(file_pattern, line)
|
||||
if found:
|
||||
files_to_compile.append(found.group(1))
|
||||
|
||||
return calls
|
||||
|
||||
def capture(self):
|
||||
cmds = self.get_infer_commands(util.get_build_output(self.build_cmd))
|
||||
clean_cmd = '%s clean' % self.build_cmd[0]
|
||||
return util.run_compilation_commands(cmds, clean_cmd)
|
@ -0,0 +1,158 @@
|
||||
(*
|
||||
* 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.
|
||||
*)
|
||||
open! IStd
|
||||
|
||||
module CLOpt = CommandLineOption
|
||||
module L = Logging
|
||||
|
||||
let infer_profile_name = "infer-capture"
|
||||
|
||||
let infer_profile = lazy
|
||||
(* indented so that users may copy it into their projects if they want to *)
|
||||
(Printf.sprintf "\
|
||||
\n <profile>\
|
||||
\n <id>%s</id>\
|
||||
\n <build>\
|
||||
\n <plugins>\
|
||||
\n <plugin>\
|
||||
\n <groupId>org.apache.maven.plugins</groupId>\
|
||||
\n <artifactId>maven-compiler-plugin</artifactId>\
|
||||
\n <configuration>\
|
||||
\n <compilerId>javac</compilerId>\
|
||||
\n <forceJavacCompilerUse>true</forceJavacCompilerUse>\
|
||||
\n <fork>true</fork>\
|
||||
\n <executable>%s</executable>\
|
||||
\n </configuration>\
|
||||
\n </plugin>\
|
||||
\n </plugins>\
|
||||
\n </build>\
|
||||
\n </profile>\
|
||||
" infer_profile_name (Config.(bin_dir ^/ string_of_analyzer Infer)))
|
||||
|
||||
let pom_worklist = ref [Config.init_work_dir]
|
||||
|
||||
let add_infer_profile_to_xml maven_xml infer_xml =
|
||||
let copy xml_in xml_out = Xmlm.output xml_out (Xmlm.input xml_in) in
|
||||
(* whether we ever found a <profiles> tag *)
|
||||
let found_profiles_tag = ref false in
|
||||
(* whether there already is an infer profile --this will always be true at the end *)
|
||||
let found_infer_profile = ref false in
|
||||
(* Process an xml document from the root. Assume the Dtd has already been handled. *)
|
||||
let rec process_root xml_in xml_out =
|
||||
process xml_in xml_out []
|
||||
and insert_infer_profile xml_out =
|
||||
let infer_xml = Xmlm.make_input ~strip:false (`String (0, Lazy.force infer_profile)) in
|
||||
Xmlm.input infer_xml |> ignore; (* skip dummy DTD *)
|
||||
process_root infer_xml xml_out
|
||||
and process xml_in xml_out tag_stack =
|
||||
let elt_in = Xmlm.input xml_in in
|
||||
match elt_in with
|
||||
| `El_start tag ->
|
||||
Xmlm.output xml_out elt_in;
|
||||
let tag_name = snd (fst tag) in
|
||||
if tag_name = "profiles" then (
|
||||
found_profiles_tag := true
|
||||
);
|
||||
process xml_in xml_out (tag_name::tag_stack)
|
||||
| `El_end ->
|
||||
(match tag_stack with
|
||||
| "profiles"::_ when not !found_infer_profile ->
|
||||
(* found the </profiles> tag but no infer profile found, add one *)
|
||||
insert_infer_profile xml_out
|
||||
| _::[] when not !found_profiles_tag->
|
||||
(* closing the root tag but no <profiles> tag found, add
|
||||
<profiles>[infer profile]</profiles> *)
|
||||
Xmlm.output xml_out (`El_start (("", "profiles"), []));
|
||||
found_profiles_tag := true; (* do not add <profiles> again *)
|
||||
insert_infer_profile xml_out;
|
||||
Xmlm.output xml_out `El_end
|
||||
| _ -> ()
|
||||
);
|
||||
Xmlm.output xml_out elt_in;
|
||||
(match tag_stack with
|
||||
| _::parent::tl ->
|
||||
process xml_in xml_out (parent::tl)
|
||||
| _::[] ->
|
||||
(* closing the first tag, we're done *)
|
||||
()
|
||||
| [] ->
|
||||
invalid_arg "ill-formed xml")
|
||||
| `Data data ->
|
||||
Xmlm.output xml_out elt_in;
|
||||
(match tag_stack with
|
||||
| "id"::"profile"::"profiles"::_ when data = infer_profile_name ->
|
||||
L.do_out "Found infer profile, not adding one@.";
|
||||
found_infer_profile := true
|
||||
| "module"::"modules"::_ ->
|
||||
let abs_data = Config.init_work_dir ^/ data in
|
||||
L.do_out "Adding maven module %s@." abs_data;
|
||||
pom_worklist := abs_data::!pom_worklist
|
||||
| _ -> ()
|
||||
);
|
||||
process xml_in xml_out tag_stack
|
||||
| `Dtd _ ->
|
||||
(* already processed the Dtd node *)
|
||||
assert false in
|
||||
let process_document () =
|
||||
(* process `Dtd; if present, it is always the first node *)
|
||||
(match Xmlm.peek maven_xml with
|
||||
| `Dtd _ ->
|
||||
copy maven_xml infer_xml
|
||||
| _ ->
|
||||
Xmlm.output infer_xml (`Dtd None)
|
||||
);
|
||||
process_root maven_xml infer_xml;
|
||||
Xmlm.eoi maven_xml |> ignore;
|
||||
if not (Xmlm.eoi maven_xml) then invalid_arg "More than one document" in
|
||||
process_document ()
|
||||
|
||||
let add_infer_profile mvn_pom infer_pom =
|
||||
let ic = In_channel.create mvn_pom in
|
||||
let with_oc out_chan =
|
||||
let with_ic () =
|
||||
let xml_in = Xmlm.make_input ~strip:false (`Channel ic) in
|
||||
let xml_out = Xmlm.make_output ~nl:true (`Channel out_chan) in
|
||||
add_infer_profile_to_xml xml_in xml_out in
|
||||
protect ~f:with_ic ~finally:(fun () -> In_channel.close ic) in
|
||||
Utils.with_file infer_pom ~f:with_oc
|
||||
|
||||
let add_profile_to_pom_in_directory dir =
|
||||
(* Even though there is a "-f" command-line arguments to change the config file Maven reads from,
|
||||
this is unreliable and Maven pretty much always reads from "pom.xml" anyway. So, we replace
|
||||
"pom.xml" with a version holding a special profile for infer capture, then put the original
|
||||
back in place. *)
|
||||
let maven_pom_path = dir ^/ "pom.xml" in
|
||||
let saved_pom_path = dir ^/ "pom.xml.infer-orig" in
|
||||
let infer_pom_path = dir ^/ "pom.xml.infer" in
|
||||
add_infer_profile maven_pom_path infer_pom_path;
|
||||
Unix.rename ~src:maven_pom_path ~dst:saved_pom_path;
|
||||
Pervasives.at_exit (fun () -> Unix.rename ~src:saved_pom_path ~dst:maven_pom_path);
|
||||
Unix.rename ~src:infer_pom_path ~dst:maven_pom_path;
|
||||
if Config.debug_mode || Config.stats_mode then
|
||||
Pervasives.at_exit (fun () -> Unix.rename ~src:maven_pom_path ~dst:infer_pom_path)
|
||||
|
||||
let capture ~prog ~args =
|
||||
while not (List.is_empty !pom_worklist); do
|
||||
let pom = List.hd_exn !pom_worklist in
|
||||
pom_worklist := List.tl_exn !pom_worklist;
|
||||
add_profile_to_pom_in_directory pom
|
||||
done;
|
||||
let extra_args = "-P"::infer_profile_name::[] in
|
||||
let capture_args = args @ extra_args in
|
||||
L.do_out "Running maven capture:@\n%s %s@." prog
|
||||
(String.concat ~sep:" " (List.map ~f:(Printf.sprintf "'%s'") capture_args));
|
||||
(* let children infer processes know that they are spawned by Maven *)
|
||||
Unix.fork_exec ~prog ~args:(prog::capture_args) ~env:Config.env_inside_maven ()
|
||||
|> Unix.waitpid
|
||||
|> function
|
||||
| Ok () -> ()
|
||||
| Error _ as status ->
|
||||
failwithf "*** ERROR: Maven command failed:@\n*** %s@\n*** %s@\n"
|
||||
(String.concat ~sep:" " (prog::capture_args))
|
||||
(Unix.Exit_or_signal.to_string_hum status)
|
@ -0,0 +1,9 @@
|
||||
(*
|
||||
* 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.
|
||||
*)
|
||||
val capture : prog:string -> args:string list -> unit
|
@ -0,0 +1,28 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.mycompany</groupId>
|
||||
<artifactId>app-with-infer-profile</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>app-with-infer-profile</name>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>infer-capture</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<compilerId>javac</compilerId>
|
||||
<forceJavacCompilerUse>true</forceJavacCompilerUse>
|
||||
<fork>true</fork>
|
||||
<executable>${project.basedir}/../../../../../bin/infer</executable>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
@ -0,0 +1 @@
|
||||
../simple_app/src
|
@ -0,0 +1,22 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.mycompany</groupId>
|
||||
<artifactId>app-with-profiles</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>app-with-profiles</name>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>some-profile</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
@ -0,0 +1 @@
|
||||
../simple_app/src
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.mycompany</groupId>
|
||||
<artifactId>module1</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>module1</name>
|
||||
</project>
|
@ -0,0 +1 @@
|
||||
../../simple_app/src
|
@ -0,0 +1,16 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.mycompany</groupId>
|
||||
<artifactId>module2</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>module2</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.mycompany</groupId>
|
||||
<artifactId>module1</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 hello2;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Random;
|
||||
|
||||
import hello.Pointers;
|
||||
import hello.Resources;
|
||||
|
||||
class Hello2 {
|
||||
|
||||
void doesNotCauseNPE2() {
|
||||
Pointers.A a = Pointers.mayReturnNull(10);
|
||||
a.method();
|
||||
}
|
||||
|
||||
void mayCauseNPE2() {
|
||||
Random rng = new Random();
|
||||
Pointers.A a = Pointers.mayReturnNull(rng.nextInt());
|
||||
// NPE
|
||||
a.method();
|
||||
}
|
||||
|
||||
void mayLeakResource2() throws IOException {
|
||||
OutputStream stream = Resources.allocateResource();
|
||||
if (stream == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
stream.write(12);
|
||||
} finally {
|
||||
// Resource leak
|
||||
}
|
||||
}
|
||||
|
||||
void twoResources2() throws IOException {
|
||||
FileInputStream fis = null;
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fis = new FileInputStream(new File("whatever.txt"));
|
||||
fos = new FileOutputStream(new File("everwhat.txt"));
|
||||
fos.write(fis.read());
|
||||
} finally {
|
||||
if (fis != null) { fis.close(); } // Resource leak
|
||||
if (fos != null) { fos.close(); }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.some.company.name</groupId>
|
||||
<artifactId>app-with-submodules</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>my app with submodules</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
<modules>
|
||||
<module>module1</module>
|
||||
<module>module2</module>
|
||||
</modules>
|
||||
</project>
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.mycompany</groupId>
|
||||
<artifactId>simple-app</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>simple-app</name>
|
||||
</project>
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 hello;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Random;
|
||||
|
||||
class Hello {
|
||||
|
||||
void doesNotCauseNPE() {
|
||||
Pointers.A a = Pointers.mayReturnNull(10);
|
||||
a.method();
|
||||
}
|
||||
|
||||
void mayCauseNPE() {
|
||||
Random rng = new Random();
|
||||
Pointers.A a = Pointers.mayReturnNull(rng.nextInt());
|
||||
// NPE
|
||||
a.method();
|
||||
}
|
||||
|
||||
void mayLeakResource() throws IOException {
|
||||
OutputStream stream = Resources.allocateResource();
|
||||
if (stream == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
stream.write(12);
|
||||
} finally {
|
||||
// Resource leak
|
||||
}
|
||||
}
|
||||
|
||||
void twoResources() throws IOException {
|
||||
FileInputStream fis = null;
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fis = new FileInputStream(new File("whatever.txt"));
|
||||
fos = new FileOutputStream(new File("everwhat.txt"));
|
||||
fos.write(fis.read());
|
||||
} finally {
|
||||
if (fis != null) { fis.close(); } // Resource leak
|
||||
if (fos != null) { fos.close(); }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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 hello;
|
||||
|
||||
public class Pointers {
|
||||
|
||||
public static class A {
|
||||
public void method() {
|
||||
}
|
||||
}
|
||||
|
||||
public static A mayReturnNull(int i) {
|
||||
if (i > 0) {
|
||||
return new A();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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 hello;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Resources {
|
||||
|
||||
public static FileOutputStream allocateResource() {
|
||||
try {
|
||||
File file = new File("foo.txt");
|
||||
return new FileOutputStream(file);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
# Copyright (c) 2016 - 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.
|
||||
|
||||
TESTS_DIR = ../..
|
||||
|
||||
ANALYZER = infer
|
||||
INFERPRINT_OPTIONS = --issues-tests
|
||||
|
||||
MVN_DIRS = app_with_submodules simple_app app_with_infer_profile app_with_profiles
|
||||
|
||||
CLEAN_EXTRA = \
|
||||
$(MVN_DIRS:%=../codetoanalyze/mvn/%/target) \
|
||||
$(MVN_DIRS:%=../codetoanalyze/mvn/%/com) \
|
||||
$(MVN_DIRS:%=infer-out-%) \
|
||||
$(MVN_DIRS:%=issues-%.exp.test)
|
||||
|
||||
include $(TESTS_DIR)/java.make
|
||||
include $(TESTS_DIR)/base.make
|
||||
|
||||
infer-out/report.json:
|
||||
$(MKDIR_P) $(@D)
|
||||
touch $@
|
||||
|
||||
infer-out-%/report.json: $(JAVA_DEPS) $(SOURCES)
|
||||
cd ../codetoanalyze/mvn/$* && \
|
||||
$(call silent_on_success,\
|
||||
$(INFER_BIN) -a $(ANALYZER) --results-dir $(CURDIR)/$(@D) \
|
||||
--project-root $(CURDIR)/$(TESTS_DIR) -- \
|
||||
$(MVN) clean compile)
|
||||
|
||||
infer-out-app_with_submodules/report.json: infer-out-simple_app/report.json
|
||||
|
||||
infer-out-simple_app/report.json: infer-out-app_with_infer_profile/report.json
|
||||
|
||||
infer-out-app_with_infer_profile/report.json: infer-out-app_with_profiles/report.json
|
||||
|
||||
issues-%.exp.test: infer-out-%/report.json
|
||||
$(INFERPRINT_BIN) -q -a $(ANALYZER) $(INFERPRINT_OPTIONS) $@ --from-json-report $<
|
||||
|
||||
issues.exp.test: $(foreach mvndir,$(MVN_DIRS),issues-$(mvndir).exp.test)
|
||||
# erase the contents of the file
|
||||
: > $@
|
||||
# remember the file name so it's easier to know which bug is from where
|
||||
for mvndir in $(MVN_DIRS); do \
|
||||
echo "-- $$mvndir" >> $@; \
|
||||
cat issues-$$mvndir.exp.test >> $@; \
|
||||
done
|
||||
|
||||
prout:
|
||||
@echo "prout: $(MVN_DIRS)"
|
||||
@echo "clean extra: $(CLEAN_EXTRA)"
|
@ -0,0 +1,19 @@
|
||||
-- app_with_submodules
|
||||
build_systems/codetoanalyze/mvn/app_with_submodules/module2/src/main/java/com/mycompany/Hello2.java, void Hello2.mayCauseNPE2(), 4, NULL_DEREFERENCE, [start of procedure mayCauseNPE2(),start of procedure mayReturnNull(...),Taking false branch,return from a call to Pointers$A Pointers.mayReturnNull(int)]
|
||||
build_systems/codetoanalyze/mvn/app_with_submodules/module2/src/main/java/com/mycompany/Hello2.java, void Hello2.mayLeakResource2(), 7, RESOURCE_LEAK, [start of procedure mayLeakResource2(),start of procedure allocateResource(),return from a call to FileOutputStream Resources.allocateResource(),Taking false branch]
|
||||
build_systems/codetoanalyze/mvn/app_with_submodules/module2/src/main/java/com/mycompany/Hello2.java, void Hello2.twoResources2(), 11, RESOURCE_LEAK, [start of procedure twoResources2(),Taking true branch,exception java.io.IOException]
|
||||
build_systems/codetoanalyze/mvn/simple_app/src/main/java/com/mycompany/Hello.java, void Hello.mayCauseNPE(), 4, NULL_DEREFERENCE, [start of procedure mayCauseNPE(),start of procedure mayReturnNull(...),Taking false branch,return from a call to Pointers$A Pointers.mayReturnNull(int)]
|
||||
build_systems/codetoanalyze/mvn/simple_app/src/main/java/com/mycompany/Hello.java, void Hello.mayLeakResource(), 7, RESOURCE_LEAK, [start of procedure mayLeakResource(),start of procedure allocateResource(),return from a call to FileOutputStream Resources.allocateResource(),Taking false branch]
|
||||
build_systems/codetoanalyze/mvn/simple_app/src/main/java/com/mycompany/Hello.java, void Hello.twoResources(), 11, RESOURCE_LEAK, [start of procedure twoResources(),Taking true branch,exception java.io.IOException]
|
||||
-- simple_app
|
||||
build_systems/codetoanalyze/mvn/simple_app/src/main/java/com/mycompany/Hello.java, void Hello.mayCauseNPE(), 4, NULL_DEREFERENCE, [start of procedure mayCauseNPE(),start of procedure mayReturnNull(...),Taking false branch,return from a call to Pointers$A Pointers.mayReturnNull(int)]
|
||||
build_systems/codetoanalyze/mvn/simple_app/src/main/java/com/mycompany/Hello.java, void Hello.mayLeakResource(), 7, RESOURCE_LEAK, [start of procedure mayLeakResource(),start of procedure allocateResource(),return from a call to FileOutputStream Resources.allocateResource(),Taking false branch]
|
||||
build_systems/codetoanalyze/mvn/simple_app/src/main/java/com/mycompany/Hello.java, void Hello.twoResources(), 11, RESOURCE_LEAK, [start of procedure twoResources(),Taking true branch,exception java.io.IOException]
|
||||
-- app_with_infer_profile
|
||||
build_systems/codetoanalyze/mvn/simple_app/src/main/java/com/mycompany/Hello.java, void Hello.mayCauseNPE(), 4, NULL_DEREFERENCE, [start of procedure mayCauseNPE(),start of procedure mayReturnNull(...),Taking false branch,return from a call to Pointers$A Pointers.mayReturnNull(int)]
|
||||
build_systems/codetoanalyze/mvn/simple_app/src/main/java/com/mycompany/Hello.java, void Hello.mayLeakResource(), 7, RESOURCE_LEAK, [start of procedure mayLeakResource(),start of procedure allocateResource(),return from a call to FileOutputStream Resources.allocateResource(),Taking false branch]
|
||||
build_systems/codetoanalyze/mvn/simple_app/src/main/java/com/mycompany/Hello.java, void Hello.twoResources(), 11, RESOURCE_LEAK, [start of procedure twoResources(),Taking true branch,exception java.io.IOException]
|
||||
-- app_with_profiles
|
||||
build_systems/codetoanalyze/mvn/simple_app/src/main/java/com/mycompany/Hello.java, void Hello.mayCauseNPE(), 4, NULL_DEREFERENCE, [start of procedure mayCauseNPE(),start of procedure mayReturnNull(...),Taking false branch,return from a call to Pointers$A Pointers.mayReturnNull(int)]
|
||||
build_systems/codetoanalyze/mvn/simple_app/src/main/java/com/mycompany/Hello.java, void Hello.mayLeakResource(), 7, RESOURCE_LEAK, [start of procedure mayLeakResource(),start of procedure allocateResource(),return from a call to FileOutputStream Resources.allocateResource(),Taking false branch]
|
||||
build_systems/codetoanalyze/mvn/simple_app/src/main/java/com/mycompany/Hello.java, void Hello.twoResources(), 11, RESOURCE_LEAK, [start of procedure twoResources(),Taking true branch,exception java.io.IOException]
|
Loading…
Reference in new issue