aboutsummaryrefslogtreecommitdiff
path: root/kotlin
diff options
context:
space:
mode:
Diffstat (limited to 'kotlin')
-rw-r--r--kotlin/common.bzl68
-rw-r--r--kotlin/common/is_eligible_friend.bzl2
-rw-r--r--kotlin/common/testing/BUILD34
-rw-r--r--kotlin/common/testing/analysis.bzl114
-rw-r--r--kotlin/common/testing/asserts.bzl116
-rw-r--r--kotlin/common/testing/testing_rules.bzl143
-rw-r--r--kotlin/common/testing/unittest_suites.bzl205
-rw-r--r--kotlin/compiler_plugin.bzl2
-rw-r--r--kotlin/jvm/testing/BUILD38
-rw-r--r--kotlin/jvm/testing/for_analysis.bzl35
-rw-r--r--kotlin/jvm/testing/jvm_compile_stubs.bzl128
-rw-r--r--kotlin/jvm/testing/jvm_import_analysis_test.bzl39
-rw-r--r--kotlin/jvm/testing/jvm_library_analysis_test.bzl155
-rw-r--r--kotlin/jvm/traverse_exports/BUILD (renamed from kotlin/jvm/internal_do_not_use/traverse_exports/BUILD)0
-rw-r--r--kotlin/jvm/traverse_exports/compiler_plugin.bzl (renamed from kotlin/jvm/internal_do_not_use/traverse_exports/compiler_plugin.bzl)2
-rw-r--r--kotlin/jvm/traverse_exports/direct_jdeps.bzl (renamed from kotlin/jvm/internal_do_not_use/traverse_exports/direct_jdeps.bzl)2
-rw-r--r--kotlin/jvm/traverse_exports/forbidden_deps.bzl (renamed from kotlin/jvm/internal_do_not_use/traverse_exports/forbidden_deps.bzl)14
-rw-r--r--kotlin/jvm/traverse_exports/friend_jars.bzl (renamed from kotlin/jvm/internal_do_not_use/traverse_exports/friend_jars.bzl)6
-rw-r--r--kotlin/jvm/traverse_exports/friend_labels.bzl (renamed from kotlin/jvm/internal_do_not_use/traverse_exports/friend_labels.bzl)6
-rw-r--r--kotlin/jvm/traverse_exports/java_plugin.bzl (renamed from kotlin/jvm/internal_do_not_use/traverse_exports/java_plugin.bzl)2
-rw-r--r--kotlin/jvm/traverse_exports/traverse_exports.bzl (renamed from kotlin/jvm/internal_do_not_use/traverse_exports/traverse_exports.bzl)4
-rw-r--r--kotlin/jvm/util/BUILD (renamed from kotlin/jvm/internal_do_not_use/util/BUILD)0
-rw-r--r--kotlin/jvm/util/file_factory.bzl (renamed from kotlin/jvm/internal_do_not_use/util/file_factory.bzl)4
-rw-r--r--kotlin/jvm/util/run_deploy_jar.bzl (renamed from kotlin/jvm/internal_do_not_use/util/run_deploy_jar.bzl)2
-rw-r--r--kotlin/jvm/util/srcjars.bzl (renamed from kotlin/jvm/internal_do_not_use/util/srcjars.bzl)2
-rw-r--r--kotlin/jvm_compile.bzl7
-rw-r--r--kotlin/jvm_import.bzl10
-rw-r--r--kotlin/jvm_library.bzl2
-rw-r--r--kotlin/jvm_test.bzl4
-rw-r--r--kotlin/traverse_exports.bzl4
30 files changed, 1081 insertions, 69 deletions
diff --git a/kotlin/common.bzl b/kotlin/common.bzl
index 2279596..cabe9fa 100644
--- a/kotlin/common.bzl
+++ b/kotlin/common.bzl
@@ -15,17 +15,17 @@
"""Common Kotlin definitions."""
load("//:visibility.bzl", "RULES_DEFS_THAT_COMPILE_KOTLIN")
-
-# go/keep-sorted start
-load("//kotlin/jvm/internal_do_not_use/util:file_factory.bzl", "FileFactory")
-load("//kotlin/jvm/internal_do_not_use/util:srcjars.bzl", "kt_srcjars")
+load("//kotlin/jvm/util:file_factory.bzl", "FileFactory")
+load("//kotlin/jvm/util:srcjars.bzl", "kt_srcjars")
load("//toolchains/kotlin_jvm:androidlint_toolchains.bzl", "androidlint_toolchains")
load("//toolchains/kotlin_jvm:kt_jvm_toolchains.bzl", "kt_jvm_toolchains")
load("@bazel_skylib//lib:sets.bzl", "sets")
load("//bazel:stubs.bzl", "lint_actions")
load("//bazel:stubs.bzl", "jspecify_flags")
+load("//bazel:stubs.bzl", "is_android_lint_exempt")
load("//bazel:stubs.bzl", "BASE_JVMOPTS")
-# go/keep-sorted end
+
+visibility(RULES_DEFS_THAT_COMPILE_KOTLIN)
# TODO: Remove the _ALLOWED_*_RULES lists to determine which rules
# are accepted dependencies to Kotlin rules as the approach does not scale
@@ -204,7 +204,7 @@ def _run_kotlinc(
} if toolchain.is_profiling_enabled(ctx.label) else {
"worker-key-mnemonic": "Kt2JavaCompile",
},
- toolchain = kt_jvm_toolchains.type,
+ toolchain = toolchain.toolchain_type,
)
return struct(
@@ -317,7 +317,7 @@ def _derive_headers(
outputs = [output_dir],
mnemonic = "KtDeriveHeaders",
progress_message = "Deriving %s: %s" % (output_dir.basename, _get_original_kt_target_label(ctx)),
- toolchain = kt_jvm_toolchains.type,
+ toolchain = toolchain.toolchain_type,
)
return [output_dir]
@@ -388,7 +388,7 @@ def _offline_instrument_jar(ctx, toolchain, jar, srcs = []):
outputs = [output],
mnemonic = "KtJaCoCoInstrument",
progress_message = "Instrumenting Kotlin for coverage collection: %s" % _get_original_kt_target_label(ctx),
- toolchain = kt_jvm_toolchains.type,
+ toolchain = toolchain.toolchain_type,
)
return output
@@ -443,7 +443,7 @@ def _merge_jdeps(ctx, kt_jvm_toolchain, jdeps_files, file_factory):
arguments = [args],
mnemonic = "KtMergeJdeps",
progress_message = "Merging jdeps files %{output}",
- toolchain = kt_jvm_toolchains.type,
+ toolchain = kt_jvm_toolchain.toolchain_type,
)
return merged_jdeps_file
@@ -504,7 +504,6 @@ def _kt_jvm_library(
common_srcs = [],
coverage_srcs = [],
java_android_lint_config = None,
- force_android_lint = False, # TODO Remove this param
manifest = None, # set for Android libs, otherwise None.
merged_manifest = None, # set for Android libs, otherwise None.
resource_files = [], # set for Android libs, otherwise empty.
@@ -576,24 +575,12 @@ def _kt_jvm_library(
# Collect all plugin data, including processors to run and all plugin classpaths,
# whether they have processors or not (b/120995492).
# This may include go/errorprone plugin classpaths that kapt will ignore.
- java_plugin_datas = kt_codegen_processing_env.get("java_plugin_data_set", depset()).to_list()
- processors_for_java_srcs = kt_codegen_processing_env.get("processors_for_java_srcs", depset()).to_list()
+ java_plugin_datas = kt_codegen_processing_env.get("java_plugin_data_set", plugins.java_plugin_datas).to_list()
+ processors_for_java_srcs = kt_codegen_processing_env.get("processors_for_java_srcs", depset(transitive = [p.processor_classes for p in java_plugin_datas])).to_list()
java_plugin_classpaths_for_java_srcs = depset(transitive = [p.processor_jars for p in java_plugin_datas])
-
- out_jars = [
- jar
- for java_info in generative_deps
- for jar in java_info.runtime_output_jars
- ]
-
- out_srcjars = [
- ] if codegen_plugin_output else []
-
- out_compilejars = [
- jar
- for java_info in generative_deps
- for jar in java_info.compile_jars.to_list()
- ]
+ out_jars = kt_codegen_processing_env.get("codegen_runtime_output_jars", [])
+ out_srcjars = kt_codegen_processing_env.get("codegen_source_jars", [])
+ out_compilejars = kt_codegen_processing_env.get("codegen_compile_jars", [])
kt_hdrs = _derive_headers(
ctx,
@@ -662,10 +649,8 @@ def _kt_jvm_library(
javac_out = output if is_android_library_without_kt_srcs_without_generative_deps else file_factory.declare_file("-libjvm-java.jar")
- annotation_plugins = list(plugins.java_plugin_infos)
-
- # Enable annotation processing for java-only sources to enable data binding
- enable_annotation_processing = True if processors_for_java_srcs else False
+ annotation_plugins = kt_codegen_processing_env.get("java_common_annotation_plugins", list(plugins.java_plugin_infos))
+ enable_annotation_processing = kt_codegen_processing_env.get("enable_java_common_annotation_processing", True)
javac_java_info = java_common.compile(
ctx,
@@ -691,14 +676,6 @@ def _kt_jvm_library(
annotation_processor_additional_inputs = annotation_processor_additional_inputs,
)
- # Directly return the JavaInfo from java.compile() for java-only android_library targets
- # to avoid creating a new JavaInfo. See b/239847857 for additional context.
- if is_android_library_without_kt_srcs_without_generative_deps:
- return struct(
- java_info = javac_java_info,
- validations = [],
- )
-
out_jars.append(javac_out)
out_srcjars.extend(javac_java_info.source_jars)
out_compilejars.extend(javac_java_info.compile_jars.to_list()) # unpack singleton depset
@@ -726,8 +703,7 @@ def _kt_jvm_library(
# TODO: Remove the is_android_library_without_kt_srcs condition once KtAndroidLint
# uses the same lint checks with AndroidLint
- disable_lint_checks = disable_lint_checks + kt_codegen_processing_env.get("disabled_lint_checks", [])
- if force_android_lint or not is_android_library_without_kt_srcs:
+ if (srcs or common_srcs or resource_files) and not is_android_lint_exempt(ctx):
lint_flags = [
"--java-language-level", # b/159950410
kt_toolchain.java_language_version,
@@ -763,10 +739,18 @@ def _kt_jvm_library(
extra_input_depsets = [p.processor_data for p in java_plugin_datas],
testonly = testonly,
android_java8_libs = kt_toolchain.android_java8_apis_desugared,
- mnemonic = "KtAndroidLint", # so LSA extractor can distinguish Kotlin (b/189442586)
+ mnemonic = "AndroidLint" if is_android_library_without_kt_srcs else "KtAndroidLint", # so LSA extractor can distinguish Kotlin (b/189442586)
)
blocking_action_outs.append(android_lint_out)
+ # Directly return the JavaInfo from java.compile() for java-only android_library targets
+ # to avoid creating a new JavaInfo. See b/239847857 for additional context.
+ if javac_java_info and is_android_library_without_kt_srcs_without_generative_deps:
+ return struct(
+ java_info = javac_java_info,
+ validations = blocking_action_outs,
+ )
+
if output_srcjar == None:
output_srcjar = file_factory.declare_file("-src.jar")
compile_jar = file_factory.declare_file("-compile.jar")
diff --git a/kotlin/common/is_eligible_friend.bzl b/kotlin/common/is_eligible_friend.bzl
index 1e5e814..0cf15d7 100644
--- a/kotlin/common/is_eligible_friend.bzl
+++ b/kotlin/common/is_eligible_friend.bzl
@@ -16,6 +16,8 @@
load("//:visibility.bzl", "RULES_DEFS_THAT_COMPILE_KOTLIN")
+visibility(RULES_DEFS_THAT_COMPILE_KOTLIN)
+
def is_eligible_friend(target, friend):
"""
Determines if `target` is allowed to use `internal` members of `friend`
diff --git a/kotlin/common/testing/BUILD b/kotlin/common/testing/BUILD
new file mode 100644
index 0000000..b3ed4eb
--- /dev/null
+++ b/kotlin/common/testing/BUILD
@@ -0,0 +1,34 @@
+# Copyright 2022 Google LLC. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the License);
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+package(
+ default_testonly = True,
+ default_visibility = ["//:internal"],
+)
+
+licenses(["notice"])
+
+bzl_library(
+ name = "testing_bzl",
+ srcs = glob(["*.bzl"]),
+ visibility = [
+ "//:internal",
+ ],
+ deps = [
+ "//:visibility_bzl",
+ "@bazel_skylib//lib:unittest",
+ ],
+)
diff --git a/kotlin/common/testing/analysis.bzl b/kotlin/common/testing/analysis.bzl
new file mode 100644
index 0000000..34cbfae
--- /dev/null
+++ b/kotlin/common/testing/analysis.bzl
@@ -0,0 +1,114 @@
+# Copyright 2022 Google LLC. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the License);
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""kt_analysis"""
+
+load("//:visibility.bzl", "RULES_KOTLIN")
+
+visibility(RULES_KOTLIN)
+
+def _get_action(actions, mnemonic):
+ """Get a specific action
+
+ Args:
+ actions: [List[Action]]
+ mnemonic: [string] Identify the action whose args to search
+
+ Returns:
+ [Action|None] The arg value, or None if it couldn't be found
+ """
+ menmonic_actions = [a for a in actions if a.mnemonic == mnemonic]
+ if len(menmonic_actions) == 0:
+ return None
+ elif len(menmonic_actions) > 1:
+ fail("Expected a single '%s' action" % mnemonic)
+
+ return menmonic_actions[0]
+
+def _get_all_args(action, arg_name, style = "trim"):
+ """Gets values for all instances of an arg name from a specific action.
+
+ Args:
+ action: [Action|None]
+ arg_name: [string]
+ style: ["trim"|"next"|"list"] The style of commandline arg
+
+ Returns:
+ [list[string]|list[list[string]]|None] The list of matching arg values
+ """
+ if not action:
+ return []
+
+ args = action.argv
+ matches = [(i, a) for (i, a) in enumerate(args) if a.startswith(arg_name)]
+
+ result = []
+ for index, arg in matches:
+ if style == "trim":
+ result.append(arg[len(arg_name):])
+ elif style == "next":
+ result.append(args[index + 1])
+ elif style == "list":
+ sub_result = []
+ for i in range(index + 1, len(args)):
+ if args[i].startswith("--"):
+ break
+ sub_result.append(args[i])
+ result.append(sub_result)
+ else:
+ fail("Unrecognized arg style '%s" % style)
+
+ return result
+
+def _get_arg(action, arg_name, style = "trim"):
+ """Gets values for exactly one instance of an arg name from a specific action.
+
+ Args:
+ action: [Action|None]
+ arg_name: [string]
+ style: ["trim"|"next"|"list"] The style of commandline arg
+
+ Returns:
+ [string|list[string]|None] The arg value, or None if it couldn't be found
+ """
+ results = _get_all_args(action, arg_name, style)
+
+ if len(results) == 0:
+ return None
+ elif len(results) == 1:
+ return results[0]
+ else:
+ fail("Expected a single '%s' arg" % arg_name)
+
+def _check_endswith_test(ctx):
+ name = ctx.label.name
+ for i in range(0, 10):
+ # TODO: Remove support for suffix digits
+ if name.endswith(str(i)):
+ name = name.removesuffix(str(i))
+ break
+ if name.endswith("_test"):
+ return
+
+ fail("Analysis test names must end in '_test'")
+
+kt_analysis = struct(
+ # go/keep-sorted start
+ DEFAULT_LIST = ["__default__"],
+ check_endswith_test = _check_endswith_test,
+ get_action = _get_action,
+ get_all_args = _get_all_args,
+ get_arg = _get_arg,
+ # go/keep-sorted end
+)
diff --git a/kotlin/common/testing/asserts.bzl b/kotlin/common/testing/asserts.bzl
new file mode 100644
index 0000000..d88796c
--- /dev/null
+++ b/kotlin/common/testing/asserts.bzl
@@ -0,0 +1,116 @@
+# Copyright 2022 Google LLC. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the License);
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""kt_asserts"""
+
+load("//:visibility.bzl", "RULES_KOTLIN")
+load("@bazel_skylib//lib:unittest.bzl", "asserts")
+
+visibility(RULES_KOTLIN)
+
+def _equals(a, b):
+ return a == b
+
+def _list_matching(left, right, matcher = None):
+ """Find the overlap between two lists.
+
+ Args:
+ left: [list[A]]
+ right: [list[B]]
+ matcher: [function(A,B):bool] A matcher on the two list types
+
+ Returns:
+ [(list[A], list[(A, B)], list[B])] The left-only, matching-pair, and right-only lists
+ """
+
+ matcher = matcher or _equals
+
+ left_only = []
+ matches = []
+ right_only = list(right)
+
+ def _process_left_ele(left_ele):
+ for index, right_ele in enumerate(right_only):
+ if matcher(left_ele, right_ele):
+ right_only.pop(index)
+ matches.append((left_ele, right_ele))
+ return
+
+ left_only.append(left_ele)
+
+ for left_ele in left:
+ _process_left_ele(left_ele)
+
+ return (left_only, matches, right_only)
+
+def _assert_list_matches(env, expected, actual, matcher = None, items_name = "items"):
+ """Assert two lists have an exact matching.
+
+ Args:
+ env: [unittest.env]
+ expected: [list[A]]
+ actual: [list[B]]
+ matcher: [function(A,B):bool]
+ items_name: [string] The plural noun describing the list items in an error message
+
+ Returns:
+ [None] Fails if assertion violated
+ """
+
+ extra_expected, _, extra_actual = _list_matching(expected, actual, matcher = matcher)
+ asserts.true(
+ env,
+ len(extra_actual) == 0 and len(extra_expected) == 0,
+ "Unmatched expected {name} {expected}\nUnmatched actual {name} {actual}".format(
+ name = items_name,
+ expected = extra_expected,
+ actual = extra_actual,
+ ),
+ )
+
+def _assert_required_mnemonic_counts(env, required_mnemonic_counts, actual_actions):
+ """Assert that some set of menemonics is present/absent within a set of Actions.
+
+ Args:
+ env: [unittest.env]
+ required_mnemonic_counts: [dict[string,string]] The menemonics to check -> expected count
+ actual_actions: [list[Action]]
+
+ Returns:
+ [None] Fails if assertion violated
+ """
+
+ considered_actual_mnemonics = [
+ x.mnemonic
+ for x in actual_actions
+ # Ignore any mnemonics not mentioned by the user
+ if (x.mnemonic in required_mnemonic_counts)
+ ]
+
+ required_mnemonics = []
+ for m, c in required_mnemonic_counts.items():
+ for _ in range(0, int(c)):
+ required_mnemonics.append(m)
+
+ _assert_list_matches(
+ env,
+ required_mnemonics,
+ considered_actual_mnemonics,
+ items_name = "mnemonics",
+ )
+
+kt_asserts = struct(
+ list_matches = _assert_list_matches,
+ required_mnemonic_counts = _assert_required_mnemonic_counts,
+)
diff --git a/kotlin/common/testing/testing_rules.bzl b/kotlin/common/testing/testing_rules.bzl
new file mode 100644
index 0000000..35359f7
--- /dev/null
+++ b/kotlin/common/testing/testing_rules.bzl
@@ -0,0 +1,143 @@
+# Copyright 2022 Google LLC. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the License);
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""kt_testing_rules"""
+
+load("//:visibility.bzl", "RULES_KOTLIN")
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
+load(":analysis.bzl", "kt_analysis")
+
+visibility(RULES_KOTLIN)
+
+# Mark targets that's aren't expected to build, but are needed for analysis test assertions.
+_ONLY_FOR_ANALYSIS_TAGS = ["manual", "nobuilder", "notap"]
+
+def _wrap_for_analysis(inner_rule):
+ """Wrap an existing rule to make it easier to use in analysis tests.
+
+ Args:
+ inner_rule: [rule|macro]
+
+ Returns:
+ [macro] Calls inner_rule with appropate tags, returning the target name
+ """
+
+ def wrapper(name, tags = [], **kwargs):
+ inner_rule(
+ name = name,
+ tags = tags + _ONLY_FOR_ANALYSIS_TAGS,
+ **kwargs
+ )
+ return name
+
+ return wrapper
+
+_assert_failure_test = analysistest.make(
+ impl = lambda ctx: _assert_failure_test_impl(ctx),
+ expect_failure = True,
+ attrs = dict(
+ msg_contains = attr.string(mandatory = True),
+ ),
+)
+
+def _assert_failure_test_impl(ctx):
+ kt_analysis.check_endswith_test(ctx)
+
+ env = analysistest.begin(ctx)
+ asserts.expect_failure(env, ctx.attr.msg_contains)
+ return analysistest.end(env)
+
+_coverage_instrumentation_test = analysistest.make(
+ impl = lambda ctx: _coverage_instrumentation_test_impl(ctx),
+ attrs = dict(
+ expected_instrumented_file_names = attr.string_list(),
+ ),
+ config_settings = {
+ "//command_line_option:collect_code_coverage": "1",
+ "//command_line_option:instrument_test_targets": "1",
+ "//command_line_option:instrumentation_filter": "+",
+ },
+)
+
+def _coverage_instrumentation_test_impl(ctx):
+ env = analysistest.begin(ctx)
+ target_under_test = analysistest.target_under_test(env)
+ instrumented_files_info = target_under_test[InstrumentedFilesInfo]
+ instrumented_files = instrumented_files_info.instrumented_files.to_list()
+ asserts.equals(
+ env,
+ ctx.attr.expected_instrumented_file_names,
+ [file.basename for file in instrumented_files],
+ )
+ return analysistest.end(env)
+
+def _create_file(name, content = ""):
+ """Declare a generated file with optional content.
+
+ Args:
+ name: [string] The relative file path
+ content: [string]
+
+ Returns:
+ [File] The label of the file
+ """
+
+ if content.startswith("\n"):
+ content = content[1:-1]
+
+ native.genrule(
+ name = "gen_" + name,
+ outs = [name],
+ cmd = """
+cat > $@ <<EOF
+%s
+EOF
+""" % content,
+ )
+
+ return name
+
+_create_dir = rule(
+ implementation = lambda ctx: _create_dir_impl(ctx),
+ attrs = dict(
+ subdir = attr.string(),
+ srcs = attr.label_list(allow_files = True),
+ ),
+)
+
+def _create_dir_impl(ctx):
+ dir = ctx.actions.declare_directory(ctx.attr.name)
+
+ command = "mkdir -p {0} " + ("&& cp {1} {0}" if ctx.files.srcs else "# {1}")
+ ctx.actions.run_shell(
+ command = command.format(
+ dir.path + "/" + ctx.attr.subdir,
+ " ".join([s.path for s in ctx.files.srcs]),
+ ),
+ inputs = ctx.files.srcs,
+ outputs = [dir],
+ )
+
+ return [DefaultInfo(files = depset([dir]))]
+
+kt_testing_rules = struct(
+ # go/keep-sorted start
+ ONLY_FOR_ANALYSIS_TAGS = _ONLY_FOR_ANALYSIS_TAGS,
+ assert_failure_test = _assert_failure_test,
+ coverage_instrumentation_test = _coverage_instrumentation_test,
+ create_dir = _wrap_for_analysis(_create_dir),
+ create_file = _create_file,
+ wrap_for_analysis = _wrap_for_analysis,
+ # go/keep-sorted end
+)
diff --git a/kotlin/common/testing/unittest_suites.bzl b/kotlin/common/testing/unittest_suites.bzl
new file mode 100644
index 0000000..b1895bf
--- /dev/null
+++ b/kotlin/common/testing/unittest_suites.bzl
@@ -0,0 +1,205 @@
+# Copyright 2022 Google LLC. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the License);
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""A framework for writing tests of Starlark code with minimal overhead.
+
+Test cases are written as Starlark functions that will eventually be executed as
+individual test targets. Two types of tests are supported: those including their
+own assertions, and those expected to call 'fail()'.
+
+Basic usage looks like:
+```
+# unittests.bzl
+load("//kotlin/common/testing:unittest_suites.bzl", "kt_unittest_suites")
+load("@bazel_skylib//lib:unittest.bzl", "asserts")
+
+unittests = kt_unittest_suite.create() # Create a new suite in this file.
+
+def _some_test_case(ctx, env):
+ # Test logic here
+ asserts.true(env, 1 == 1)
+ return [] # Return any declared files
+
+unittests.expect_finish(_some_test_case) # Include the test case in the suite
+
+def _some_fail_case(ctx):
+ # No assertions are allowed in fail cases
+ _some_logic_that_should_call_fail(ctx)
+
+unittests.expect_fail(_some_fail_case, "fail message substring") # Expect this case to call fail
+
+# Generate a pair of rules that will be used for test targets
+_test, _fail = unittests.close() # @unused
+```
+
+```
+// BUILD
+load(":unittests.bzl", "unittests")
+
+# Render each test case as a target in this package
+unittests.render(
+ name = "unittests"
+)
+```
+"""
+
+load("//:visibility.bzl", "RULES_KOTLIN")
+load("@bazel_skylib//lib:unittest.bzl", "unittest")
+load(":testing_rules.bzl", "kt_testing_rules")
+
+visibility(RULES_KOTLIN)
+
+def _create():
+ """Create a new test suite.
+
+ Returns:
+ [kt_unittest_suite] An object representing the suite under construction
+ """
+
+ test_cases = dict()
+ rule_holder = [] # Use a list rather than separate vars becase captured vars are final
+
+ def expect_fail(test_case, msg_contains):
+ """Add a test case to the suite which is expected to call fail.
+
+ Args:
+ test_case: [function(ctx)]
+ msg_contains: [string] A substring expected in the failure message
+ """
+
+ if rule_holder:
+ fail("Test suite is closed")
+
+ test_case_name = _fn_name(test_case)
+ if not test_case_name.startswith("_"):
+ fail("Test cases must be private '%s'" % test_case_name)
+ if test_case_name in test_cases:
+ fail("Existing test case named '%s'" % test_case_name)
+
+ test_cases[test_case_name] = struct(
+ impl = test_case,
+ msg_contains = msg_contains,
+ )
+
+ def expect_finish(test_case):
+ """Add a test case to the suite.
+
+ Args:
+ test_case: [function(ctx,unittest.env):None|list[File]]
+ """
+
+ expect_fail(test_case, None)
+
+ def close():
+ """Close the suite from expect_finishing new tests.
+
+ The return value must be assigned to '_test, _fail' with an '# @unused' suppression.
+
+ Returns:
+ [(rule, rule)]
+ """
+
+ if rule_holder:
+ fail("Test suite is closed")
+
+ def test_impl(ctx):
+ env = unittest.begin(ctx)
+
+ output_files = test_cases[ctx.attr.case_name].impl(ctx, env) or []
+ if output_files:
+ ctx.actions.run_shell(
+ outputs = output_files,
+ command = "exit 1",
+ )
+
+ return unittest.end(env) + [OutputGroupInfo(_file_sink = depset(output_files))]
+
+ test_rule = unittest.make(
+ impl = test_impl,
+ attrs = dict(case_name = attr.string()),
+ )
+ rule_holder.append(test_rule)
+
+ def fail_impl(ctx):
+ test_cases[ctx.attr.case_name].impl(ctx)
+ return []
+
+ fail_rule = rule(
+ implementation = fail_impl,
+ attrs = dict(case_name = attr.string()),
+ )
+ rule_holder.append(fail_rule)
+
+ # Rules must be assigned to top-level Starlark vars before being called
+ return test_rule, fail_rule
+
+ def render(name, tags = [], **kwargs):
+ """Render the test suite into targets.
+
+ Args:
+ name: [string]
+ tags: [list[string]]
+ **kwargs: Generic rule kwargs
+ """
+
+ if not rule_holder:
+ fail("Test suite is not closed")
+ test_rule = rule_holder[0]
+ fail_rule = rule_holder[1]
+
+ test_targets = []
+ for test_case_name, test_case_data in test_cases.items():
+ target_name = test_case_name.removeprefix("_") + "_test"
+ test_targets.append(target_name)
+
+ if test_case_data.msg_contains == None:
+ test_rule(
+ name = target_name,
+ tags = tags,
+ case_name = test_case_name,
+ **kwargs
+ )
+ else:
+ fail_rule(
+ name = test_case_name,
+ tags = tags + kt_testing_rules.ONLY_FOR_ANALYSIS_TAGS,
+ case_name = test_case_name,
+ **kwargs
+ )
+ kt_testing_rules.assert_failure_test(
+ name = target_name,
+ target_under_test = test_case_name,
+ msg_contains = test_case_data.msg_contains,
+ )
+
+ native.test_suite(
+ name = name,
+ tests = test_targets,
+ **kwargs
+ )
+
+ return struct(
+ expect_finish = expect_finish,
+ expect_fail = expect_fail,
+ close = close,
+ render = render,
+ )
+
+def _fn_name(rule_or_fn):
+ parts = str(rule_or_fn).removeprefix("<").removesuffix(">").split(" ")
+ return parts[0] if (len(parts) == 1) else parts[1]
+
+kt_unittest_suites = struct(
+ create = _create,
+)
diff --git a/kotlin/compiler_plugin.bzl b/kotlin/compiler_plugin.bzl
index 5df6e68..e1854e4 100644
--- a/kotlin/compiler_plugin.bzl
+++ b/kotlin/compiler_plugin.bzl
@@ -16,6 +16,8 @@
load("//:visibility.bzl", "RULES_KOTLIN")
+visibility(RULES_KOTLIN)
+
KtCompilerPluginInfo, _make_kt_compiler_plugin_info = provider(
doc = "Info for running a plugin that directly registers itself to kotlinc extension points",
fields = dict(
diff --git a/kotlin/jvm/testing/BUILD b/kotlin/jvm/testing/BUILD
new file mode 100644
index 0000000..59bd24c
--- /dev/null
+++ b/kotlin/jvm/testing/BUILD
@@ -0,0 +1,38 @@
+# Copyright 2022 Google LLC. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the License);
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+package(
+ default_applicable_licenses = ["//:license"],
+ default_testonly = True,
+ default_visibility = ["//:internal"],
+)
+
+licenses(["notice"])
+
+bzl_library(
+ name = "testing_bzl",
+ srcs = glob(["*.bzl"]),
+ visibility = [
+ "//:internal",
+ ],
+ deps = [
+ "//:visibility_bzl",
+ "//kotlin:rules_bzl",
+ "//kotlin/common/testing:testing_bzl",
+ "@bazel_skylib//lib:sets",
+ "@bazel_skylib//lib:unittest",
+ ],
+)
diff --git a/kotlin/jvm/testing/for_analysis.bzl b/kotlin/jvm/testing/for_analysis.bzl
new file mode 100644
index 0000000..1ba4fcd
--- /dev/null
+++ b/kotlin/jvm/testing/for_analysis.bzl
@@ -0,0 +1,35 @@
+# Copyright 2022 Google LLC. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the License);
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""kt_for_analysis"""
+
+load("//:visibility.bzl", "RULES_KOTLIN")
+load("//kotlin:compiler_plugin.bzl", "kt_compiler_plugin")
+load("//kotlin:jvm_import.bzl", "kt_jvm_import")
+load("//kotlin:jvm_library.bzl", "kt_jvm_library")
+load("//kotlin/common/testing:testing_rules.bzl", "kt_testing_rules")
+
+visibility(RULES_KOTLIN)
+
+kt_for_analysis = struct(
+ # go/keep-sorted start
+ java_binary = kt_testing_rules.wrap_for_analysis(native.java_binary),
+ java_import = kt_testing_rules.wrap_for_analysis(native.java_import),
+ java_library = kt_testing_rules.wrap_for_analysis(native.java_library),
+ java_plugin = kt_testing_rules.wrap_for_analysis(native.java_plugin),
+ kt_compiler_plugin = kt_testing_rules.wrap_for_analysis(kt_compiler_plugin),
+ kt_jvm_import = kt_testing_rules.wrap_for_analysis(kt_jvm_import),
+ kt_jvm_library = kt_testing_rules.wrap_for_analysis(kt_jvm_library),
+ # go/keep-sorted end
+)
diff --git a/kotlin/jvm/testing/jvm_compile_stubs.bzl b/kotlin/jvm/testing/jvm_compile_stubs.bzl
new file mode 100644
index 0000000..0d5a573
--- /dev/null
+++ b/kotlin/jvm/testing/jvm_compile_stubs.bzl
@@ -0,0 +1,128 @@
+# Copyright 2022 Google LLC. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the License);
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""kt_jvm_compile_stubs"""
+
+load("//:visibility.bzl", "RULES_KOTLIN")
+load("//kotlin:common.bzl", "common")
+load("//kotlin:jvm_compile.bzl", "kt_jvm_compile")
+load("//kotlin:traverse_exports.bzl", "kt_traverse_exports")
+load("//kotlin/common/testing:analysis.bzl", "kt_analysis")
+load("//kotlin/common/testing:testing_rules.bzl", "kt_testing_rules")
+load("//toolchains/kotlin_jvm:java_toolchains.bzl", "java_toolchains")
+load("//toolchains/kotlin_jvm:kt_jvm_toolchains.bzl", "kt_jvm_toolchains")
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
+
+visibility(RULES_KOTLIN)
+
+_kt_jvm_compile_stub_rule = rule(
+ implementation = lambda ctx: _kt_jvm_compile_stub_rule_impl(ctx),
+ attrs = dict(
+ srcs = attr.label_list(
+ allow_files = True,
+ ),
+ common_srcs = attr.label_list(
+ allow_files = True,
+ ),
+ deps = attr.label_list(
+ aspects = [kt_traverse_exports.aspect],
+ providers = [JavaInfo],
+ ),
+ exports = attr.label_list(
+ aspects = [kt_traverse_exports.aspect],
+ providers = [JavaInfo],
+ ),
+ rule_family = attr.int(
+ default = common.RULE_FAMILY.UNKNOWN,
+ ),
+ r_java = attr.label(
+ providers = [JavaInfo],
+ ),
+ _java_toolchain = attr.label(
+ default = Label(
+ "@bazel_tools//tools/jdk:current_java_toolchain",
+ ),
+ ),
+ ),
+ fragments = ["java"],
+ outputs = dict(
+ jar = "lib%{name}.jar",
+ ),
+ toolchains = [kt_jvm_toolchains.type, "@bazel_tools//tools/jdk:toolchain_type"],
+)
+
+def _kt_jvm_compile_stub_rule_impl(ctx):
+ # As additional capabilites need to be tested, this rule should support
+ # additional fields/attributes.
+ result = kt_jvm_compile(
+ ctx,
+ output = ctx.outputs.jar,
+ srcs = ctx.files.srcs,
+ common_srcs = ctx.files.common_srcs,
+ deps = ctx.attr.deps,
+ plugins = [],
+ exported_plugins = [],
+ runtime_deps = [],
+ exports = ctx.attr.exports,
+ javacopts = [],
+ kotlincopts = [],
+ neverlink = False,
+ testonly = False,
+ android_lint_plugins = [],
+ manifest = None,
+ merged_manifest = None,
+ resource_files = [],
+ rule_family = ctx.attr.rule_family,
+ kt_toolchain = kt_jvm_toolchains.get(ctx),
+ java_toolchain = java_toolchains.get(ctx),
+ disable_lint_checks = [],
+ r_java = ctx.attr.r_java[JavaInfo] if ctx.attr.r_java else None,
+ )
+ return [result.java_info]
+
+_kt_jvm_compile_stub_analysis_test = analysistest.make(
+ impl = lambda ctx: _kt_jvm_compile_stub_analysis_test_impl(ctx),
+ attrs = dict(
+ expected_kotlinc_classpath_names = attr.string_list(default = kt_analysis.DEFAULT_LIST),
+ ),
+)
+
+def _kt_jvm_compile_stub_analysis_test_impl(ctx):
+ kt_analysis.check_endswith_test(ctx)
+
+ env = analysistest.begin(ctx)
+
+ actions = analysistest.target_actions(env)
+ kotlinc_action = kt_analysis.get_action(actions, "Kt2JavaCompile")
+
+ asserts.true(
+ env,
+ JavaInfo in ctx.attr.target_under_test,
+ "Did not produce JavaInfo provider.",
+ )
+
+ if ctx.attr.expected_kotlinc_classpath_names != kt_analysis.DEFAULT_LIST:
+ kotlinc_classpath = kt_analysis.get_arg(kotlinc_action, "-cp", style = "next").split(":")
+ asserts.equals(
+ env,
+ ctx.attr.expected_kotlinc_classpath_names,
+ [file.rsplit("/", 1)[1] for file in kotlinc_classpath],
+ )
+
+ return analysistest.end(env)
+
+kt_jvm_compile_stubs = struct(
+ rule = kt_testing_rules.wrap_for_analysis(_kt_jvm_compile_stub_rule),
+ analysis_test = _kt_jvm_compile_stub_analysis_test,
+)
diff --git a/kotlin/jvm/testing/jvm_import_analysis_test.bzl b/kotlin/jvm/testing/jvm_import_analysis_test.bzl
new file mode 100644
index 0000000..55df268
--- /dev/null
+++ b/kotlin/jvm/testing/jvm_import_analysis_test.bzl
@@ -0,0 +1,39 @@
+# Copyright 2022 Google LLC. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the License);
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""kt_jvm_import_analysis_test"""
+
+load("//:visibility.bzl", "RULES_KOTLIN")
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
+
+visibility(RULES_KOTLIN)
+
+kt_jvm_import_analysis_test = analysistest.make(
+ impl = lambda ctx: _kt_jvm_import_analysis_test_impl(ctx),
+ attrs = dict(),
+)
+
+def _kt_jvm_import_analysis_test_impl(ctx):
+ env = analysistest.begin(ctx)
+ asserts.true(
+ env,
+ JavaInfo in ctx.attr.target_under_test,
+ "kt_jvm_import did not produce JavaInfo provider.",
+ )
+ asserts.true(
+ env,
+ ProguardSpecProvider in ctx.attr.target_under_test,
+ "kt_jvm_import did not produce ProguardSpecProvider provider.",
+ )
+ return analysistest.end(env)
diff --git a/kotlin/jvm/testing/jvm_library_analysis_test.bzl b/kotlin/jvm/testing/jvm_library_analysis_test.bzl
new file mode 100644
index 0000000..6e05b28
--- /dev/null
+++ b/kotlin/jvm/testing/jvm_library_analysis_test.bzl
@@ -0,0 +1,155 @@
+# Copyright 2022 Google LLC. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the License);
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""kt_jvm_library_analysis_test"""
+
+load("//:visibility.bzl", "RULES_KOTLIN")
+load("//kotlin/common/testing:analysis.bzl", "kt_analysis")
+load("//kotlin/common/testing:asserts.bzl", "kt_asserts")
+load("@bazel_skylib//lib:sets.bzl", "sets")
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
+
+visibility(RULES_KOTLIN)
+
+kt_jvm_library_analysis_test = analysistest.make(
+ impl = lambda ctx: _kt_jvm_library_analysis_test_impl(ctx),
+ attrs = dict(
+ expected_al_ruleset_names = attr.string_list(
+ doc = "Android Lint rule JARs reported as run on the given target",
+ default = kt_analysis.DEFAULT_LIST,
+ ),
+ expected_compile_jar_names = attr.string_list(
+ doc = "Names of all JavaInfo::compile_jars for the given target",
+ default = kt_analysis.DEFAULT_LIST,
+ ),
+ expected_exported_processor_jar_names = attr.string_list(
+ doc = "Names of all JavaInfo::plugins JARs returned by the given target",
+ default = kt_analysis.DEFAULT_LIST,
+ ),
+ expected_exported_processor_classes = attr.string_list(
+ doc = "Annotation processors reported as to be run on depending targets",
+ ),
+ expected_processor_classes = attr.string_list(
+ doc = "Annotation processors reported as run on the given target",
+ ),
+ expected_kotlinc_plugin_jar_names = attr.string_list(
+ doc = "Names of all -Xplugin= JARs",
+ default = kt_analysis.DEFAULT_LIST,
+ ),
+ expected_friend_jar_names = attr.string_list(
+ doc = "Names of all -Xfriend-paths= JARs",
+ default = kt_analysis.DEFAULT_LIST,
+ ),
+ expected_runfile_names = attr.string_list(
+ doc = "Names of all runfiles",
+ default = kt_analysis.DEFAULT_LIST,
+ ),
+ expect_jdeps = attr.bool(default = True),
+ expect_processor_classpath = attr.bool(),
+ expect_neverlink = attr.bool(),
+ required_mnemonic_counts = attr.string_dict(
+ doc = "Expected mnemonics to expected action count; unlisted mnemonics are ignored",
+ ),
+ ),
+)
+
+def _kt_jvm_library_analysis_test_impl(ctx):
+ kt_analysis.check_endswith_test(ctx)
+
+ env = analysistest.begin(ctx)
+ actual = ctx.attr.target_under_test
+
+ actions = analysistest.target_actions(env)
+ kt_al_action = kt_analysis.get_action(actions, "KtAndroidLint")
+
+ asserts.true(
+ env,
+ JavaInfo in actual,
+ "kt_jvm_library did not produce JavaInfo provider.",
+ )
+ asserts.true(
+ env,
+ ProguardSpecProvider in actual,
+ "Expected a ProguardSpecProvider provider.",
+ )
+
+ if ctx.attr.expected_runfile_names != kt_analysis.DEFAULT_LIST:
+ asserts.set_equals(
+ env,
+ sets.make(ctx.attr.expected_runfile_names),
+ sets.make([
+ f.basename
+ for f in actual[DefaultInfo].data_runfiles.files.to_list()
+ ]),
+ )
+
+ if ctx.attr.expected_compile_jar_names != kt_analysis.DEFAULT_LIST:
+ asserts.set_equals(
+ env,
+ sets.make(ctx.attr.expected_compile_jar_names),
+ sets.make([f.basename for f in actual[JavaInfo].compile_jars.to_list()]),
+ "kt_jvm_library JavaInfo::compile_jars",
+ )
+
+ if ctx.attr.expected_exported_processor_jar_names != kt_analysis.DEFAULT_LIST:
+ asserts.set_equals(
+ env,
+ sets.make(ctx.attr.expected_exported_processor_jar_names),
+ sets.make([f.basename for f in actual[JavaInfo].plugins.processor_jars.to_list()]),
+ )
+
+ asserts.set_equals(
+ env,
+ sets.make(ctx.attr.expected_exported_processor_classes),
+ sets.make(actual[JavaInfo].plugins.processor_classes.to_list()),
+ )
+
+ kt_2_java_compile = kt_analysis.get_action(actions, "Kt2JavaCompile")
+
+ if kt_2_java_compile:
+ asserts.true(
+ env,
+ kt_2_java_compile.outputs.to_list()[0].basename.endswith(".jar"),
+ "Expected first output to be a JAR (this affects the param file name).",
+ )
+
+ if ctx.attr.expected_friend_jar_names != kt_analysis.DEFAULT_LIST:
+ friend_paths_arg = kt_analysis.get_arg(kt_2_java_compile, "-Xfriend-paths=")
+ kt_asserts.list_matches(
+ env,
+ expected = ["/" + x for x in ctx.attr.expected_friend_jar_names],
+ actual = friend_paths_arg.split(",") if friend_paths_arg else [],
+ matcher = lambda expected, actual: actual.endswith(expected),
+ items_name = "friend JARs",
+ )
+
+ if ctx.attr.expected_kotlinc_plugin_jar_names != kt_analysis.DEFAULT_LIST:
+ kt_asserts.list_matches(
+ env,
+ expected = ["/" + x for x in ctx.attr.expected_kotlinc_plugin_jar_names],
+ actual = kt_analysis.get_all_args(kt_2_java_compile, "-Xplugin="),
+ matcher = lambda expected, actual: actual.endswith(expected),
+ items_name = "kotlinc plugin JARs",
+ )
+
+ asserts.equals(
+ env,
+ ctx.attr.expect_neverlink,
+ len(actual[JavaInfo].transitive_runtime_jars.to_list()) == 0,
+ "Mismatch: Expected transitive_runtime_jars iff (neverlink == False)",
+ )
+
+ kt_asserts.required_mnemonic_counts(env, ctx.attr.required_mnemonic_counts, actions)
+
+ return analysistest.end(env)
diff --git a/kotlin/jvm/internal_do_not_use/traverse_exports/BUILD b/kotlin/jvm/traverse_exports/BUILD
index 9b5382c..9b5382c 100644
--- a/kotlin/jvm/internal_do_not_use/traverse_exports/BUILD
+++ b/kotlin/jvm/traverse_exports/BUILD
diff --git a/kotlin/jvm/internal_do_not_use/traverse_exports/compiler_plugin.bzl b/kotlin/jvm/traverse_exports/compiler_plugin.bzl
index a5c65c4..4a52cb5 100644
--- a/kotlin/jvm/internal_do_not_use/traverse_exports/compiler_plugin.bzl
+++ b/kotlin/jvm/traverse_exports/compiler_plugin.bzl
@@ -17,6 +17,8 @@
load("//:visibility.bzl", "RULES_KOTLIN")
load("//kotlin:compiler_plugin.bzl", "KtCompilerPluginInfo")
+visibility(RULES_KOTLIN)
+
def _get_exported_plugins(_target, ctx_rule):
return [
t[KtCompilerPluginInfo]
diff --git a/kotlin/jvm/internal_do_not_use/traverse_exports/direct_jdeps.bzl b/kotlin/jvm/traverse_exports/direct_jdeps.bzl
index 8bbb75f..75e2a15 100644
--- a/kotlin/jvm/internal_do_not_use/traverse_exports/direct_jdeps.bzl
+++ b/kotlin/jvm/traverse_exports/direct_jdeps.bzl
@@ -16,6 +16,8 @@
load("//:visibility.bzl", "RULES_KOTLIN")
+visibility(RULES_KOTLIN)
+
def _get_jdeps(target, _ctx_rule):
return [
out.compile_jdeps
diff --git a/kotlin/jvm/internal_do_not_use/traverse_exports/forbidden_deps.bzl b/kotlin/jvm/traverse_exports/forbidden_deps.bzl
index fa1db86..570b260 100644
--- a/kotlin/jvm/internal_do_not_use/traverse_exports/forbidden_deps.bzl
+++ b/kotlin/jvm/traverse_exports/forbidden_deps.bzl
@@ -20,21 +20,19 @@ Currently this system recognizes:
- targets exporting other forbidden targets
"""
-load("@bazel_skylib//lib:sets.bzl", "sets")
-load("//bazel:stubs.bzl", "EXEMPT_DEPS", "FORBIDDEN_DEP_PACKAGES")
load("//:visibility.bzl", "RULES_KOTLIN")
+load("//bazel:stubs.bzl", "is_exempt_dep", "is_forbidden_dep")
+
+visibility(RULES_KOTLIN)
def _error(target, msg):
return (str(target.label), msg)
-def _is_exempt(target):
- return sets.contains(EXEMPT_DEPS, str(target.label))
-
def _check_forbidden(target, ctx_rule):
- if _is_exempt(target):
+ if is_exempt_dep(target):
return []
- if sets.contains(FORBIDDEN_DEP_PACKAGES, target.label.package):
+ if is_forbidden_dep(target):
return [_error(target, "Forbidden package")]
# Identify nano protos using tag (b/122083175)
@@ -45,7 +43,7 @@ def _check_forbidden(target, ctx_rule):
return []
def _if_not_checked(target):
- return [] if _is_exempt(target) else [_error(target, "Not checked")]
+ return [] if is_exempt_dep(target) else [_error(target, "Not checked")]
def _validate_deps(error_set):
if not error_set:
diff --git a/kotlin/jvm/internal_do_not_use/traverse_exports/friend_jars.bzl b/kotlin/jvm/traverse_exports/friend_jars.bzl
index 3f89905..4d34abd 100644
--- a/kotlin/jvm/internal_do_not_use/traverse_exports/friend_jars.bzl
+++ b/kotlin/jvm/traverse_exports/friend_jars.bzl
@@ -14,10 +14,10 @@
"""kt_friend_jars_visitor"""
-# go/keep-sorted start
-load("//kotlin/common:is_eligible_friend.bzl", "is_eligible_friend")
load("//:visibility.bzl", "RULES_KOTLIN")
-# go/keep-sorted end
+load("//kotlin/common:is_eligible_friend.bzl", "is_eligible_friend")
+
+visibility(RULES_KOTLIN)
def _get_output_jars(target, _ctx_rule):
# We can't simply use `JavaInfo.compile_jars` because we only want the JARs directly created by
diff --git a/kotlin/jvm/internal_do_not_use/traverse_exports/friend_labels.bzl b/kotlin/jvm/traverse_exports/friend_labels.bzl
index ef0aacd..c91340c 100644
--- a/kotlin/jvm/internal_do_not_use/traverse_exports/friend_labels.bzl
+++ b/kotlin/jvm/traverse_exports/friend_labels.bzl
@@ -14,10 +14,10 @@
"""kt_friend_labels_visitor"""
-# go/keep-sorted start
-load("//kotlin/common:is_eligible_friend.bzl", "is_eligible_friend")
load("//:visibility.bzl", "RULES_KOTLIN")
-# go/keep-sorted end
+load("//kotlin/common:is_eligible_friend.bzl", "is_eligible_friend")
+
+visibility(RULES_KOTLIN)
def _get_output_labels(target, _):
return [target.label]
diff --git a/kotlin/jvm/internal_do_not_use/traverse_exports/java_plugin.bzl b/kotlin/jvm/traverse_exports/java_plugin.bzl
index b993b75..3ee38ef 100644
--- a/kotlin/jvm/internal_do_not_use/traverse_exports/java_plugin.bzl
+++ b/kotlin/jvm/traverse_exports/java_plugin.bzl
@@ -21,6 +21,8 @@ from the way that java targets handles plugins.
load("//:visibility.bzl", "RULES_KOTLIN")
+visibility(RULES_KOTLIN)
+
def _get_java_plugins(_target, ctx_rule):
return [
t[JavaPluginInfo].plugins
diff --git a/kotlin/jvm/internal_do_not_use/traverse_exports/traverse_exports.bzl b/kotlin/jvm/traverse_exports/traverse_exports.bzl
index edf2a10..c32f3a4 100644
--- a/kotlin/jvm/internal_do_not_use/traverse_exports/traverse_exports.bzl
+++ b/kotlin/jvm/traverse_exports/traverse_exports.bzl
@@ -14,7 +14,6 @@
"""Combined aspect for all rules_kotlin behaviours that need to traverse exports."""
-# go/keep-sorted start
load("//:visibility.bzl", "RULES_KOTLIN")
load(":compiler_plugin.bzl", "kt_compiler_plugin_visitor")
load(":direct_jdeps.bzl", "kt_direct_jdeps_visitor")
@@ -22,7 +21,8 @@ load(":forbidden_deps.bzl", "kt_forbidden_deps_visitor")
load(":friend_jars.bzl", "kt_friend_jars_visitor")
load(":friend_labels.bzl", "kt_friend_labels_visitor")
load(":java_plugin.bzl", "java_plugin_visitor")
-# go/keep-sorted end
+
+visibility(RULES_KOTLIN)
# java_xxx_proto_library don't populate java_outputs but we can get them through
# required_aspect_providers from their proto_library deps.
diff --git a/kotlin/jvm/internal_do_not_use/util/BUILD b/kotlin/jvm/util/BUILD
index 157c675..157c675 100644
--- a/kotlin/jvm/internal_do_not_use/util/BUILD
+++ b/kotlin/jvm/util/BUILD
diff --git a/kotlin/jvm/internal_do_not_use/util/file_factory.bzl b/kotlin/jvm/util/file_factory.bzl
index 2e076c3..49791f7 100644
--- a/kotlin/jvm/internal_do_not_use/util/file_factory.bzl
+++ b/kotlin/jvm/util/file_factory.bzl
@@ -16,6 +16,8 @@
load("//:visibility.bzl", "RULES_KOTLIN")
+visibility(RULES_KOTLIN)
+
def FileFactory(ctx, base):
"""Creates files with names derived from some base file or prefix
@@ -31,7 +33,7 @@ def FileFactory(ctx, base):
FileFactory
"""
- if type(base) == "File":
+ if type(base) != "string":
base = _scrub_base_file(ctx, base)
def declare_directory(suffix):
diff --git a/kotlin/jvm/internal_do_not_use/util/run_deploy_jar.bzl b/kotlin/jvm/util/run_deploy_jar.bzl
index 14c784b..d4d087a 100644
--- a/kotlin/jvm/internal_do_not_use/util/run_deploy_jar.bzl
+++ b/kotlin/jvm/util/run_deploy_jar.bzl
@@ -19,6 +19,8 @@ load("//:visibility.bzl", "RULES_KOTLIN")
load("//bazel:stubs.bzl", "BASE_JVMOPTS")
# go/keep-sorted end
+visibility(RULES_KOTLIN)
+
def kt_run_deploy_jar(
ctx,
java_runtime,
diff --git a/kotlin/jvm/internal_do_not_use/util/srcjars.bzl b/kotlin/jvm/util/srcjars.bzl
index becf573..01618d9 100644
--- a/kotlin/jvm/internal_do_not_use/util/srcjars.bzl
+++ b/kotlin/jvm/util/srcjars.bzl
@@ -19,6 +19,8 @@ load("//:visibility.bzl", "RULES_KOTLIN")
load(":run_deploy_jar.bzl", "kt_run_deploy_jar")
# go/keep-sorted end
+visibility(RULES_KOTLIN)
+
def _zip(
ctx,
kt_jvm_toolchain,
diff --git a/kotlin/jvm_compile.bzl b/kotlin/jvm_compile.bzl
index 58a2818..be5fda0 100644
--- a/kotlin/jvm_compile.bzl
+++ b/kotlin/jvm_compile.bzl
@@ -20,6 +20,8 @@ load(":common.bzl", "common")
load(":compiler_plugin.bzl", "KtCompilerPluginInfo")
load(":traverse_exports.bzl", "kt_traverse_exports")
+visibility(RULES_DEFS_THAT_COMPILE_KOTLIN)
+
_RULE_FAMILY = common.RULE_FAMILY
def kt_jvm_compile(
@@ -39,7 +41,6 @@ def kt_jvm_compile(
resource_files,
exported_plugins,
java_android_lint_config = None,
- force_android_lint = False, # TODO Remove this param
manifest = None,
merged_manifest = None,
classpath_resources = [],
@@ -75,7 +76,6 @@ def kt_jvm_compile(
resource_files: List of Files. The list of Android Resource files.
exported_plugins: List of exported javac/kotlinc plugins
java_android_lint_config: Android Lint XML config file to use if there are no Kotlin srcs
- force_android_lint: Force AndroidLint action
manifest: A File. The raw Android manifest. Optional.
merged_manifest: A File. The merged Android manifest. Optional.
classpath_resources: List of Files. The list of classpath resources (kt_jvm_library only).
@@ -116,7 +116,7 @@ def kt_jvm_compile(
if classpath_resources and rule_family != _RULE_FAMILY.JVM_LIBRARY:
fail("resources attribute only allowed for jvm libraries")
- if type(java_toolchain) != "JavaToolchainInfo":
+ if type(java_toolchain) == "Target":
# Allow passing either a target or a provider until all callers are updated
java_toolchain = java_toolchain[java_common.JavaToolchainInfo]
@@ -187,7 +187,6 @@ def kt_jvm_compile(
),
),
java_android_lint_config = java_android_lint_config,
- force_android_lint = force_android_lint,
resource_files = resource_files,
runtime_deps = [d[JavaInfo] for d in runtime_deps if JavaInfo in d],
srcs = srcs,
diff --git a/kotlin/jvm_import.bzl b/kotlin/jvm_import.bzl
index 72b5f6e..cfdb474 100644
--- a/kotlin/jvm_import.bzl
+++ b/kotlin/jvm_import.bzl
@@ -14,13 +14,15 @@
"""Kotlin kt_jvm_import rule."""
-load(":common.bzl", "common")
-load(":traverse_exports.bzl", "kt_traverse_exports")
-load("//toolchains/kotlin_jvm:kt_jvm_toolchains.bzl", "kt_jvm_toolchains")
+load("//:visibility.bzl", "RULES_KOTLIN")
load("//toolchains/kotlin_jvm:java_toolchains.bzl", "java_toolchains")
+load("//toolchains/kotlin_jvm:kt_jvm_toolchains.bzl", "kt_jvm_toolchains")
load("@bazel_skylib//lib:dicts.bzl", "dicts")
+load(":common.bzl", "common")
load(":compiler_plugin.bzl", "KtCompilerPluginInfo")
-load("//:visibility.bzl", "RULES_KOTLIN")
+load(":traverse_exports.bzl", "kt_traverse_exports")
+
+visibility(RULES_KOTLIN)
def _kt_jvm_import_impl(ctx):
kt_jvm_toolchain = kt_jvm_toolchains.get(ctx)
diff --git a/kotlin/jvm_library.bzl b/kotlin/jvm_library.bzl
index ad77dbd..816ea25 100644
--- a/kotlin/jvm_library.bzl
+++ b/kotlin/jvm_library.bzl
@@ -22,6 +22,8 @@ load("//bazel:stubs.bzl", "LINT_REGISTRY")
load("//bazel:stubs.bzl", "registry_checks_for_package")
load(":jvm_library.internal.bzl", "kt_jvm_library_helper")
+visibility(RULES_KOTLIN)
+
def kt_jvm_library(
name,
srcs = None,
diff --git a/kotlin/jvm_test.bzl b/kotlin/jvm_test.bzl
index 2a85a66..8c9ca84 100644
--- a/kotlin/jvm_test.bzl
+++ b/kotlin/jvm_test.bzl
@@ -14,9 +14,11 @@
"""Kotlin macro for building and running tests on a JVM."""
-load(":jvm_library.bzl", "kt_jvm_library")
load("//bazel:stubs.bzl", "register_extension_info")
load("//:visibility.bzl", "RULES_KOTLIN")
+load(":jvm_library.bzl", "kt_jvm_library")
+
+visibility(RULES_KOTLIN)
def _lib_name(name):
return "%s_DO_NOT_DEPEND_LIB" % name
diff --git a/kotlin/traverse_exports.bzl b/kotlin/traverse_exports.bzl
index 8157ec1..bb8b81d 100644
--- a/kotlin/traverse_exports.bzl
+++ b/kotlin/traverse_exports.bzl
@@ -14,7 +14,9 @@
"""Combined aspect for all rules_kotlin behaviours that need to traverse exports."""
-load("//kotlin/jvm/internal_do_not_use/traverse_exports:traverse_exports.bzl", _kt_traverse_exports = "kt_traverse_exports")
load("//:visibility.bzl", "RULES_DEFS_THAT_COMPILE_KOTLIN")
+load("//kotlin/jvm/traverse_exports:traverse_exports.bzl", _kt_traverse_exports = "kt_traverse_exports")
+
+visibility(RULES_DEFS_THAT_COMPILE_KOTLIN)
kt_traverse_exports = _kt_traverse_exports