# 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.

.PHONY: default
default: infer

ROOT_DIR = .
include $(ROOT_DIR)/Makefile.config

MAKE_SOURCE = $(MAKE) -C $(SRC_DIR)

ifneq ($(UTOP),no)
BUILD_SYSTEMS_TESTS += infertop
endif

ifeq ($(BUILD_C_ANALYZERS),yes)
BUILD_SYSTEMS_TESTS += \
  annotation-reachability-sources-override \
  assembly \
  backtrack_level \
  ck_imports \
  clang_compilation_db_escaped clang_compilation_db_relpath \
  clang_multiple_files \
  clang_translation \
  clang_unknown_ext \
  clang_with_block_listed_flags \
  clang_with_E_flag \
  clang_with_M_flag \
  clang_with_MD_flag \
  deduplicate_template_warnings \
  delete_results_dir \
  disjunctive_domain \
  duplicate_symbols \
  fail_on_issue \
  j1 \
  linters \
  project_root_rel \
  reactive \
  results_xml \
  tracebugs \
  utf8_in_procname \
  export_changed_functions \
  incremental_analysis_remove_file \
  incremental_analysis_change_procedure \
  incremental_analysis_add_procedure \

COST_TESTS += \
  c_performance \

DIRECT_TESTS += \
  c_biabduction \
  c_bufferoverrun \
  c_frontend \
  c_performance \
  c_pulse \
  c_pulse-isl \
  c_purity \
  c_uninit \
  cpp_annotation-reachability \
  cpp_biabduction \
  cpp_bufferoverrun \
  cpp_conflicts \
  cpp_frontend \
  cpp_impurity \
  cpp_linters \
  cpp_linters-for-test-only \
  cpp_liveness \
  cpp_performance \
  cpp_pulse \
  cpp_pulse-isl \
  cpp_quandary \
  cpp_racerd \
  cpp_siof \
  cpp_starvation \
  cpp_uninit \

ifneq ($(BUCK),no)
BUILD_SYSTEMS_TESTS += \
  buck_block_list \
  buck-clang-db \
  buck_clang_test_determinator \
  buck_flavors \
  buck_flavors_diff \
  buck_flavors_run \
  buck_flavors_deterministic \
  buck_export_changed_functions \

endif
ifneq ($(CMAKE),no)
BUILD_SYSTEMS_TESTS += clang_compilation_db cmake inferconfig inferconfig_not_strict
endif
ifneq ($(NDKBUILD),no)
BUILD_SYSTEMS_TESTS += ndk_build
endif
ifeq ($(HAS_OBJC),yes)
BUILD_SYSTEMS_TESTS += \
  clang_test_determinator \
  objc_getters_setters \
  objc_missing_fld \
  objc_retain_cycles \
  objc_retain_cycles_weak \
  differential_of_costs_report_objc \

COST_TESTS += \
  objc_autoreleasepool \
  objc_performance \

DIRECT_TESTS += \
  objc_autoreleasepool \
  objc_bufferoverrun \
  objc_biabduction \
  objc_frontend \
  objc_linters \
  objc_linters-def-folder \
  objc_linters-for-test-only \
  objc_liveness \
  objc_performance \
  objc_pulse \
  objc_quandary \
  objc_self-in-block \
  objc_uninit \
  objcpp_biabduction \
  objcpp_frontend \
  objcpp_linters \
  objcpp_linters-for-test-only \
  objcpp_liveness \
  objcpp_pulse \
  objcpp_racerd \
  objcpp_retain-cycles \

ifeq ($(IS_FACEBOOK_TREE),yes)
BUILD_SYSTEMS_TESTS += \
  fb_differential_of_config_impact_report_objc

DIRECT_TESTS += \
  objc_fb-config-impact \
  objc_fb-gk-interaction
endif


ifneq ($(XCODE_SELECT),no)
BUILD_SYSTEMS_TESTS += xcodebuild_no_xcpretty
endif
ifneq ($(XCPRETTY),no)
BUILD_SYSTEMS_TESTS += xcodebuild
endif
endif # HAS_OBJC
endif # BUILD_C_ANALYZERS

ifeq ($(BUILD_ERLANG_ANALYZERS),yes)
ifneq ($(REBAR3),no)
DIRECT_TESTS += \
  erlang_nonmatch \
  erlang_topl \
  erlang_features \

BUILD_SYSTEMS_TESTS += rebar3
endif
endif # BUILD_ERLANG_ANALYZERS

ifeq ($(BUILD_JAVA_ANALYZERS),yes)
BUILD_SYSTEMS_TESTS += \
  differential_interesting_paths_filter \
  differential_of_costs_report_java \
  incremental_analysis_cost_change \
  differential_skip_anonymous_class_renamings \
  differential_skip_duplicated_types_on_filenames \
  differential_skip_duplicated_types_on_filenames_with_renamings \
  gradle \
  java_source_parser \
  java_test_determinator \
  javac \
  resource_leak_exception_lines \
  racerd_dedup

COST_TESTS += \
  java_hoistingExpensive \
  java_performance \
  java_performance-exclusive \

DIRECT_TESTS += \
  java_annotreach \
  java_biabduction \
  java_bufferoverrun \
  java_checkers \
  java_hoisting \
  java_hoistingExpensive \
  java_impurity \
  java_immutability \
  java_inefficientKeysetIterator \
  java_litho-required-props \
  java_nullsafe \
  java_nullsafe-annotation-graph \
  java_performance \
  java_performance-exclusive \
  java_pulse \
  java_pulse-isl \
  java_purity \
  java_quandary \
  java_racerd \
  java_starvation \
  java_starvation-dedup \
  java_starvation-whole-program \
  java_topl \

ifneq ($(KOTLINC), no)
DIRECT_TESTS += \
	kotlin_racerd \

endif

# javac has trouble running in parallel on the same files
direct_java_pulse-isl_test: direct_java_pulse_test

ifeq ($(IS_FACEBOOK_TREE),yes)
BUILD_SYSTEMS_TESTS += \
  fb_differential_of_config_impact_report_java

COST_TESTS += java_fb-performance

DIRECT_TESTS += \
  java_fb-config-impact \
  java_fb-config-impact-paths \
  java_fb-config-impact-strict \
  java_fb-gk-interaction \
  java_fb-immutability \
  java_fb-performance
endif

ifneq ($(ANT),no)
BUILD_SYSTEMS_TESTS += ant
endif
ifneq ($(BUCK),no)
BUILD_SYSTEMS_TESTS += buck_java_flavor
endif
ifneq ($(MVN),no)
BUILD_SYSTEMS_TESTS += mvn
endif
endif # BUILD_JAVA_ANALYZERS

DIRECT_TESTS += \
  dotnet_arithmetic \
  dotnet_array \
  dotnet_bgeble \
  dotnet_box \
  dotnet_fieldderef \
  dotnet_isinst \
  dotnet_ldstr \
  dotnet_logical \
  dotnet_nullderef-interproc \
  dotnet_nullderef-simple \
  dotnet_nullparam \
  dotnet_numcomparison \
  dotnet_reference \
  dotnet_resourceleak \
  dotnet_starg

ifeq ($(BUILD_C_ANALYZERS)+$(BUILD_JAVA_ANALYZERS),yes+yes)
BUILD_SYSTEMS_TESTS += make utf8_in_pwd waf
endif

ifeq ($(IS_INFER_RELEASE),no)
configure: configure.ac $(wildcard m4version-$(INFER_MAJOR).$(INFER_MINOR).$(INFER_PATCH)* ; \
	sed -i -e '/"$(INFER_MAJOR).$(INFER_MINOR).$(INFER_PATCH)"/d' versions.json ; \
	yarn run docusaurus docs:version $(INFER_MAJOR).$(INFER_MINOR).$(INFER_PATCH)
#	copy static versioned resources
	cd $(WEBSITE_DIR)/static/man && \
	rm -fr $(INFER_MAJOR).$(INFER_MINOR).$(INFER_PATCH)/ ; \
	cp -a next/ $(INFER_MAJOR).$(INFER_MINOR).$(INFER_PATCH)/
	cd $(WEBSITE_DIR)/static/odoc && \
	rm -fr $(INFER_MAJOR).$(INFER_MINOR).$(INFER_PATCH)/ ; \
	cp -a next/ $(INFER_MAJOR).$(INFER_MINOR).$(INFER_PATCH)/
#	adjust intra-doc paths in new doc version
	cd $(WEBSITE_DIR)/versioned_docs/version-$(INFER_MAJOR).$(INFER_MINOR).$(INFER_PATCH)/ && \
	find . -type f -not -name versions.md \
	  -exec sed -i -e 's#/docs/next/#/docs/#g' \{\} \+
#	adjust paths to static versioned resources in new doc version
	cd $(WEBSITE_DIR)/versioned_docs/version-$(INFER_MAJOR).$(INFER_MINOR).$(INFER_PATCH)/ && \
	find . -type f -not -name versions.md \
	  -exec sed -i -e 's#/next/#/$(INFER_MAJOR).$(INFER_MINOR).$(INFER_PATCH)/#g' \{\} \+
#	adjust intra-doc links in the previous "latest" version: /docs/foo -> /docs/<oldlatest>/foo
#	  select the first version that is not the one we are creating (in case this target is run
#	  multiple times)
	old_latest=$$(jq 'map(select(. != "$(INFER_MAJOR).$(INFER_MINOR).$(INFER_PATCH)"))[0]' < $(WEBSITE_DIR)/versions.json | tr -d '"'); \
	cd $(WEBSITE_DIR)/versioned_docs/version-$${old_latest}/ && \
	find . -type f -not -name versions.md \
	  -exec sed -i -e "s#(/docs/\([^$$(echo $$old_latest | cut -b 1)]\)#(/docs/$${old_latest}/\1#g" \{\} \+
#	adjust versions.md, the page where users can navigate to other versions of the docs, unless
#	it was already changed by an earlier run of this rule
	cd $(WEBSITE_DIR)/ && \
	grep -q -F 'latest released version ($(INFER_MAJOR).$(INFER_MINOR).$(INFER_PATCH))' docs/versions.md || \
	find docs versioned_docs -name versions.md \
	  -exec sed -i -e 's#^- \[latest released version (\([^)]*\))\](/docs/getting-started)$$#- [latest released version ($(INFER_MAJOR).$(INFER_MINOR).$(INFER_PATCH))](/docs/getting-started)\n- [previous version (\1)](/docs/\1/getting-started)#' \{\} \+

# print list of targets
.PHONY: show-targets
show-targets:
	$(QUIET)$(MAKE) -pqrR . | grep --only-matching -e '^[a-zA-Z0-9][^ ]*:' | cut -d ':' -f 1 | sort
