diff --git a/.gitignore b/.gitignore index 23aca02d4..0c29ae1dc 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,6 @@ /_build /_build_logs /infer/lib/erlang/infer_parse_transform/_build -/infer/lib/erlang/infer_parse_transform/rebar.lock /infer/tests/codetoanalyze/java/*/codetoanalyze _build_infer *.exp.test* @@ -41,6 +40,7 @@ duplicates.txt /infer/tests/build_systems/codetoanalyze/ndk-build/hello_app/libs/ /infer/tests/build_systems/codetoanalyze/ndk-build/hello_app/obj/ /infer/tests/build_systems/codetoanalyze/path with spaces/ +/infer/tests/build_systems/codetoanalyze/rebar3/erl_hi/_build /infer/tests/build_systems/codetoanalyze/utf8_*n_pwd /infer/tests/build_systems/codetoanalyze/xcodebuild/simple_app/app_built /infer/tests/build_systems/codetoanalyze/xcodebuild/simple_app/build/ @@ -164,6 +164,20 @@ infer/src/.project # generated by Maven /infer/annotations/target +# generated by Erlang/Rebar3 +*.beam +*.plt +*.swo +.erlang.cookie +.eunit +.rebar +.rebar3 +ebin +erl_crash.dump +rebar.lock +rebar3.crashdump + + # dune /infer/_build /infer/dune-workspace diff --git a/Makefile b/Makefile index 9ace8c9a6..82fe1e63a 100644 --- a/Makefile +++ b/Makefile @@ -212,6 +212,9 @@ endif ifneq ($(MVN),no) BUILD_SYSTEMS_TESTS += mvn endif +ifneq ($(REBAR3),no) +BUILD_SYSTEMS_TESTS += rebar3 +endif endif DIRECT_TESTS += \ diff --git a/Makefile.autoconf.in b/Makefile.autoconf.in index 5ce651cc5..00a3c8727 100644 --- a/Makefile.autoconf.in +++ b/Makefile.autoconf.in @@ -74,6 +74,7 @@ OTOOL = @OTOOL@ PATCHELF = @PATCHELF@ PATH = @PATH@ prefix = @prefix@ +REBAR3 = @REBAR3@ SDKROOT = @SDKROOT@ SHASUM = @SHASUM@ USER_JAVA_HOME = @USER_JAVA_HOME@ diff --git a/configure.ac b/configure.ac index a5c35441d..aa2a1fc2d 100644 --- a/configure.ac +++ b/configure.ac @@ -386,7 +386,7 @@ if test x"$NDKBUILD" = x"no"; then fi AC_CHECK_TOOL([NINJA], [ninja], [no]) - +AC_CHECK_TOOL([REBAR3], [rebar3], [no]) AC_CHECK_TOOL([XCPRETTY], [xcpretty], [no]) AC_CHECK_TOOL([SED], [sed], [no]) diff --git a/infer/src/integration/Rebar3.ml b/infer/src/integration/Rebar3.ml index e5ab5b092..e96db5b06 100644 --- a/infer/src/integration/Rebar3.ml +++ b/infer/src/integration/Rebar3.ml @@ -6,6 +6,18 @@ *) open! IStd +module L = Logging -(* TODO *) -let capture ~args:_ = () +let run_rebar result_dir args = + let args = [result_dir; "--"; "rebar3"] @ args in + let prog = Config.lib_dir ^/ "erlang" ^/ "erlang.sh" in + L.debug Capture Verbose "executing %s@." prog ; + Process.create_process_and_wait ~prog ~args + + +let capture ~args = + let in_dir = ResultsDir.get_path Temporary in + let rebar_result_dir = Filename.temp_dir ~in_dir "rebar3infer" "" in + run_rebar rebar_result_dir args ; + (* TODO: parse the JSON files *) + if not Config.debug_mode then Utils.rmtree rebar_result_dir diff --git a/infer/src/scripts/checkCopyright.ml b/infer/src/scripts/checkCopyright.ml index f390a780e..2a0ac6130 100644 --- a/infer/src/scripts/checkCopyright.ml +++ b/infer/src/scripts/checkCopyright.ml @@ -27,6 +27,10 @@ let comment_style_al = Line ("//", false) let comment_style_c = Block ("/*", "*", "*/", false) +let comment_style_erlang = Line ("%", false) + +let comment_style_lisp = Line (";", false) + let comment_style_llvm = Line (";", true) let comment_style_m4 = Line ("dnl", false) @@ -41,11 +45,10 @@ let comment_style_python = Line ("#", false) let comment_style_shell = Line ("#", true) -let comment_style_lisp = Line (";", false) - let comment_styles_lang = [ (comment_style_al, "AL") ; (comment_style_c, "C") + ; (comment_style_erlang, "Erlang") ; (comment_style_lisp, "Lisp") ; (comment_style_llvm, "LLVM") ; (comment_style_m4, "M4") @@ -227,9 +230,11 @@ type inferred_comment_style = let com_style_of_lang = [ (".ac", Resolved comment_style_m4) ; (".al", Resolved comment_style_al) + ; (".app.src", Resolved comment_style_erlang) ; (".atd", Resolved comment_style_ocaml) ; (".c", Resolved comment_style_c) ; (".cpp", Resolved comment_style_c) + ; (".erl", Resolved comment_style_erlang) ; (".h", Resolved comment_style_c) ; (".inc", Resolved comment_style_c) ; (".java", Resolved comment_style_c) @@ -255,7 +260,8 @@ let com_style_of_lang = ; ("dune-project", Resolved comment_style_lisp) ; ("dune-workspace", Resolved comment_style_lisp) ; ("dune-workspace.in", Resolved comment_style_lisp) - ; ("Makefile", Resolved comment_style_make) ] + ; ("Makefile", Resolved comment_style_make) + ; ("rebar.config", Resolved comment_style_erlang) ] let tuareg_magic_style_line = "(* -*- tuareg -*- *)" diff --git a/infer/tests/build_systems/codetoanalyze/rebar3/erl_hi/README b/infer/tests/build_systems/codetoanalyze/rebar3/erl_hi/README new file mode 100644 index 000000000..9c2fb8ccf --- /dev/null +++ b/infer/tests/build_systems/codetoanalyze/rebar3/erl_hi/README @@ -0,0 +1,5 @@ +1. Start an Erlang shell: + rebar3 shell + +2. Run main function: + erl_hi_app:main(). diff --git a/infer/tests/build_systems/codetoanalyze/rebar3/erl_hi/rebar.config b/infer/tests/build_systems/codetoanalyze/rebar3/erl_hi/rebar.config new file mode 100644 index 000000000..9df9626fe --- /dev/null +++ b/infer/tests/build_systems/codetoanalyze/rebar3/erl_hi/rebar.config @@ -0,0 +1,11 @@ +% Copyright (c) Facebook, Inc. and its affiliates. +% +% This source code is licensed under the MIT license found in the +% LICENSE file in the root directory of this source tree. + +{erl_opts, []}. +{deps, []}. + +{shell, [ + {apps, [erl_hi]} +]}. diff --git a/infer/tests/build_systems/codetoanalyze/rebar3/erl_hi/src/erl_hi.app.src b/infer/tests/build_systems/codetoanalyze/rebar3/erl_hi/src/erl_hi.app.src new file mode 100644 index 000000000..6593525b2 --- /dev/null +++ b/infer/tests/build_systems/codetoanalyze/rebar3/erl_hi/src/erl_hi.app.src @@ -0,0 +1,14 @@ +% Copyright (c) Facebook, Inc. and its affiliates. +% +% This source code is licensed under the MIT license found in the +% LICENSE file in the root directory of this source tree. +{application, erl_hi, [ + {description, "A simple Erlang application"}, + {vsn, "0.1.0"}, + {registered, []}, + {applications, [ + kernel, + stdlib + ]}, + {modules, []} +]}. diff --git a/infer/tests/build_systems/codetoanalyze/rebar3/erl_hi/src/erl_hi_app.erl b/infer/tests/build_systems/codetoanalyze/rebar3/erl_hi/src/erl_hi_app.erl new file mode 100644 index 000000000..cd92efd82 --- /dev/null +++ b/infer/tests/build_systems/codetoanalyze/rebar3/erl_hi/src/erl_hi_app.erl @@ -0,0 +1,48 @@ +% Copyright (c) Facebook, Inc. and its affiliates. +% +% This source code is licensed under the MIT license found in the +% LICENSE file in the root directory of this source tree. + +-module(erl_hi_app). + +-export([main/0]). + +odd_matcher([_, _ | T]) -> + odd_matcher(T); +odd_matcher([_]) -> + ok. + +maybe_good_matcher([_]) -> + ok; +maybe_good_matcher(Xs) -> + case length(Xs) rem 2 of + 0 -> maybe_good_matcher(half_it(Xs)); + 1 -> maybe_good_matcher(Xs ++ Xs ++ Xs ++ [rabbit]) + end. + +half_it([]) -> + []; +half_it([_, X | T]) -> + [X | half_it(T)]. + +guarded(Xs) -> + if + length(Xs) rem 2 == 1 -> odd_matcher(Xs); + true -> ok + end. + +main() -> + % ok + maybe_good_matcher("odd"), + % ok + maybe_good_matcher("even"), + % ok + guarded("odd"), + % ok + guarded("even"), + % ok + odd_matcher("odd"), + % nok [FN] + odd_matcher("even"), + % nok [FN] (not a good matcher after all) + maybe_good_matcher(""). diff --git a/infer/tests/build_systems/rebar3/Makefile b/infer/tests/build_systems/rebar3/Makefile new file mode 100644 index 000000000..9d5ddf97b --- /dev/null +++ b/infer/tests/build_systems/rebar3/Makefile @@ -0,0 +1,41 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +TESTS_DIR = ../.. + +INFERPRINT_OPTIONS = --issues-tests + +REBAR3_DIRS = erl_hi + +CLEAN_EXTRA = \ + $(REBAR3_DIRS:%=../codetoanalyze/rebar3/%/target) \ + $(REBAR3_DIRS:%=../codetoanalyze/rebar3/%/com) \ + $(REBAR3_DIRS:%=infer-out-%) \ + $(REBAR3_DIRS:%=issues-%.exp.test) + +include $(TESTS_DIR)/infer.make + +infer-out/report.json: + $(QUIET)$(MKDIR_P) $(@D) + $(QUIET)touch $@ + +infer-out-%/report.json: $(JAVA_DEPS) $(SOURCES) + $(QUIET)cd ../codetoanalyze/rebar3/$* && \ + $(call silent_on_success,Testing rebar3 Erlang integration: $*,\ + $(INFER_BIN) --results-dir $(CURDIR)/$(@D) \ + --project-root $(CURDIR)/$(TESTS_DIR) -- \ + $(REBAR3) compile) + +issues-%.exp.test: infer-out-%/report.json + $(QUIET)$(INFER_BIN) report -q $(INFERPRINT_OPTIONS) $@ -o $( $@ +# remember the file name so it's easier to know which bug is from where + $(QUIET)for r3dir in $(REBAR3_DIRS); do \ + echo "-- $$r3dir" >> $@; \ + cat issues-$$r3dir.exp.test >> $@; \ + done diff --git a/infer/tests/build_systems/rebar3/issues.exp b/infer/tests/build_systems/rebar3/issues.exp new file mode 100644 index 000000000..8db4037a8 --- /dev/null +++ b/infer/tests/build_systems/rebar3/issues.exp @@ -0,0 +1 @@ +-- erl_hi