Reviewed By: jeremydubreil Differential Revision: D15518291 fbshipit-source-id: 5cd0d3941master
parent
bc61543875
commit
d3cf79a095
@ -0,0 +1,9 @@
|
||||
[buildfile]
|
||||
includes = //DEFS
|
||||
|
||||
[project]
|
||||
ignore = .git, .ml, .mli
|
||||
|
||||
[java]
|
||||
source_level = 8
|
||||
target_level = 8
|
@ -0,0 +1 @@
|
||||
../../../../.buckversion
|
@ -0,0 +1,88 @@
|
||||
import os
|
||||
|
||||
original_java_library = java_library
|
||||
original_android_library = android_library
|
||||
|
||||
def _get_infer_bin():
|
||||
return read_config("infer", "infer_bin")
|
||||
|
||||
def _get_project_root():
|
||||
return read_config("infer", "project_root")
|
||||
|
||||
def _get_infer_deps():
|
||||
infer_out = read_config("infer", "infer_out")
|
||||
infer_deps = "{}/infer-deps.txt".format(infer_out)
|
||||
return infer_deps
|
||||
|
||||
def _infer_capture_genrule(
|
||||
name,
|
||||
srcs
|
||||
):
|
||||
|
||||
args = [
|
||||
"--jobs",
|
||||
"1",
|
||||
"--genrule-mode",
|
||||
"--quiet",
|
||||
"--no-progress-bar",
|
||||
"--results-dir",
|
||||
"$OUT",
|
||||
"--sourcepath",
|
||||
"$SRCDIR",
|
||||
"--project-root",
|
||||
_get_project_root(),
|
||||
"--classpath",
|
||||
"$(classpath :{})".format(name),
|
||||
"--generated-classes",
|
||||
"$(location :{})".format(name),
|
||||
"capture",
|
||||
]
|
||||
|
||||
args_file = os.path.join("$TMP", "args.txt")
|
||||
subcommands = [
|
||||
"echo {} >> {}".format(arg, args_file)
|
||||
for arg in args
|
||||
] + [
|
||||
" ".join([_get_infer_bin(), "@" + args_file]),
|
||||
# need to use a cross-platform kind of flock to avoid fragmentation
|
||||
'echo -e "_\\t_\\t$OUT" >> {}'.format(_get_infer_deps())
|
||||
]
|
||||
|
||||
genrule(
|
||||
name = name + "_infer_capture",
|
||||
srcs = srcs,
|
||||
cmd = " && ".join(subcommands),
|
||||
out = "infer_out",
|
||||
labels = ["infer_capture_genrule"],
|
||||
)
|
||||
|
||||
|
||||
def _make_infer_capture_genrule(name, kwargs):
|
||||
java_sources = [
|
||||
f
|
||||
for f in kwargs.get("srcs", [])
|
||||
if f.endswith(".java")
|
||||
]
|
||||
|
||||
if java_sources != []:
|
||||
_infer_capture_genrule(name, java_sources)
|
||||
kwargs["labels"] = kwargs.get("labels", []) + ["infer_enabled"]
|
||||
|
||||
return kwargs
|
||||
|
||||
|
||||
def java_library(name, **kwargs):
|
||||
new_kwargs = _make_infer_capture_genrule(name, kwargs)
|
||||
|
||||
original_java_library(
|
||||
name=name,
|
||||
**new_kwargs
|
||||
)
|
||||
|
||||
def android_library(name, **kwargs):
|
||||
new_kwargs = _make_infer_capture_genrule(name, kwargs)
|
||||
|
||||
original_android_library(
|
||||
name=name,
|
||||
**new_kwargs
|
||||
)
|
@ -0,0 +1,24 @@
|
||||
# Copyright (c) 2016-present, Facebook, Inc.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
TESTS_DIR = ../..
|
||||
ROOT_DIR = $(TESTS_DIR)/../..
|
||||
|
||||
ANALYSE = $(ROOT_DIR)/scripts/genrule_run.sh
|
||||
BUCK_TARGET = //module2:module2
|
||||
INFER_OUT = $(shell pwd)/infer-out
|
||||
CLEAN_EXTRA = buck-out
|
||||
SOURCES = $(shell find . -name '*.java')
|
||||
|
||||
INFERPRINT_OPTIONS = --issues-tests
|
||||
INFER_OPTIONS = --debug-exceptions
|
||||
|
||||
include $(TESTS_DIR)/infer.make
|
||||
|
||||
$(INFER_OUT)/report.json: $(MAKEFILE_LIST) $(SOURCES)
|
||||
$(QUIET) $(REMOVE_DIR) buck-out && \
|
||||
$(call silent_on_success,Testing genrule capture integration in $(TEST_REL_DIR),\
|
||||
$(ANALYSE) $(BUCK_TARGET) $(INFER_OUT) $(INFER_OPTIONS))
|
||||
|
@ -0,0 +1,7 @@
|
||||
java_library(
|
||||
name='annotations',
|
||||
srcs=['ThreadSafe.java'],
|
||||
visibility=[
|
||||
'PUBLIC'
|
||||
],
|
||||
)
|
@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2018-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
package genrulecapture.annotations;
|
||||
|
||||
public @interface ThreadSafe {}
|
@ -0,0 +1,2 @@
|
||||
module2/Class2.java, genrulecapture.module2.Class2.get():int, 22, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to int Class1.get(),access to `this.c.x`,<Write trace>,call to void Class1.set(int),access to `this.c.x`]
|
||||
module2/Class2.java, genrulecapture.module2.Class2.set(int):void, 18, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [call to void Class1.set(int),access to `this.c.x`]
|
@ -0,0 +1,10 @@
|
||||
java_library(
|
||||
name='module1',
|
||||
srcs=glob(["*.java"]),
|
||||
deps=[
|
||||
'//annotations:annotations',
|
||||
],
|
||||
visibility=[
|
||||
'PUBLIC'
|
||||
],
|
||||
)
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package genrulecapture.module1;
|
||||
|
||||
public class Class1 {
|
||||
int x;
|
||||
|
||||
public void set(int d) {
|
||||
x = d;
|
||||
}
|
||||
|
||||
public int get() {
|
||||
return x;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
java_library(
|
||||
name='module2',
|
||||
srcs=glob(["*.java"]),
|
||||
deps=[
|
||||
'//module1:module1',
|
||||
'//annotations:annotations',
|
||||
'//module3:module3',
|
||||
]
|
||||
)
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package genrulecapture.module2;
|
||||
|
||||
import genrulecapture.annotations.ThreadSafe;
|
||||
import genrulecapture.module1.Class1;
|
||||
|
||||
@ThreadSafe
|
||||
public class Class2 {
|
||||
Class1 c;
|
||||
|
||||
void set(int x) {
|
||||
c.set(x);
|
||||
}
|
||||
|
||||
int get() {
|
||||
return c.get();
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
cxx_library(
|
||||
name = 'module3',
|
||||
visibility = [
|
||||
'PUBLIC',
|
||||
],
|
||||
srcs = [
|
||||
'some_c_code.c',
|
||||
],
|
||||
)
|
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) 2019-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void some_c_func() {
|
||||
int* s = NULL;
|
||||
*s = 42;
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2019-present, Facebook, Inc.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
BUCK=buck
|
||||
GENRULE_SUFFIX="_infer_capture"
|
||||
BUCK_KIND_PATTERN="^(java|android)_library$"
|
||||
INFER_BIN="${INFER_BIN:-infer}"
|
||||
|
||||
INFER_VERSION=$(${INFER_BIN} --version | head -1 | cut -f3 -d' ')
|
||||
|
||||
ROOT_TARGET="${1?Must specify a root target.}"
|
||||
shift
|
||||
QUERY="kind('${BUCK_KIND_PATTERN}', deps('${ROOT_TARGET}'))"
|
||||
QUERY="attrfilter(labels, infer_enabled, ${QUERY})"
|
||||
|
||||
INFER_OUT="${1?Must specify an infer out location.}"
|
||||
if [[ "$INFER_OUT" != /* ]] ; then
|
||||
echo "Must use absolute path for infer out location."
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
|
||||
BUCK_CONFIG="--config infer.project_root=${PWD}"
|
||||
BUCK_CONFIG="${BUCK_CONFIG} --config infer.infer_out=${INFER_OUT}"
|
||||
BUCK_CONFIG="${BUCK_CONFIG} --config infer.infer_bin=${INFER_BIN}"
|
||||
BUCK_CONFIG="${BUCK_CONFIG} --config infer.enabled=True"
|
||||
BUCK_CONFIG="${BUCK_CONFIG} --config infer.version=${INFER_VERSION}"
|
||||
|
||||
# prepare infer-out, mainly for runstate
|
||||
$INFER_BIN -o "${INFER_OUT}" > /dev/null 2>&1
|
||||
|
||||
TARGET_FILE=$(mktemp)
|
||||
trap "{ rm -f $TARGET_FILE; }" EXIT
|
||||
|
||||
echo "Running buck query."
|
||||
$BUCK query ${BUCK_CONFIG} "${QUERY}" | sed "s/\$/${GENRULE_SUFFIX}/" > "${TARGET_FILE}"
|
||||
|
||||
if [ -s "${TARGET_FILE}" ]
|
||||
then
|
||||
echo "Found $(wc -l < ${TARGET_FILE}) targets."
|
||||
else
|
||||
echo "Zero targets found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo 'Running genrule capture under buck.'
|
||||
$BUCK build --no-cache ${BUCK_CONFIG} "@${TARGET_FILE}"
|
||||
|
||||
echo 'Running merge and analysis.'
|
||||
$INFER_BIN analyze --genrule-master-mode -o "${INFER_OUT}" "$@"
|
Loading…
Reference in new issue