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