Snap for 9411666 from 0f80a73bcfbfe68325763f2905916c4f414b3446 to udc-d1-release

Change-Id: I820fb42858081e5334d9191096f6589386698c7d
diff --git a/METADATA b/METADATA
index b7570de..9e9632a 100644
--- a/METADATA
+++ b/METADATA
@@ -11,8 +11,8 @@
     type: GIT
     value: "https://team.googlesource.com/kotlin-rules/rules"
   }
-  version: "f4178248eea802a9c26f501bac7df4afd04445c3"
-  last_upgrade_date { year: 2022 month: 12 day: 9}
+  version: "0904db290987a7e48a708369e5093b6d033769e7"
+  last_upgrade_date { year: 2022 month: 12 day: 14}
   license_type: NOTICE
 }
 
diff --git a/kotlin/common.bzl b/kotlin/common.bzl
index 16ad59e..3789b0c 100644
--- a/kotlin/common.bzl
+++ b/kotlin/common.bzl
@@ -507,33 +507,24 @@
         jdeps_output = None,
         deps_checker = None,
         java_toolchain = None):
-    # Direct compile_jars before transitive not to confuse strict_deps (b/149107867)
-    full_classpath = depset(
-        order = "preorder",
-        transitive = [merged_deps.compile_jars, merged_deps.transitive_compile_time_jars],
-    )
+    full_classpath = _create_classpath(java_toolchain, [merged_deps])
     label = _get_original_kt_target_label(ctx)
-    bootclasspath = java_toolchain.bootclasspath
 
     args = ctx.actions.args()
     args.add("--jdeps_output", jdeps_output)
     args.add_all(jars_to_check, before_each = "--input")
-    args.add_all(bootclasspath, before_each = "--bootclasspath_entry")
+    args.add_all(java_toolchain.bootclasspath, before_each = "--bootclasspath_entry")
     args.add_all(full_classpath, before_each = "--classpath_entry")
     if enforce_strict_deps:
         args.add_all(merged_deps.compile_jars, before_each = "--directdep")
-    args.add("--checking_mode=%s" % ("error" if enforce_strict_deps else "silence"))
+    args.add("error" if enforce_strict_deps else "silence", format = "--checking_mode=%s")
     args.add("--nocheck_missing_members")  # compiler was happy so no need
-    args.add("--rule_label")
-    args.add(label)
+    args.add("--rule_label", label)
 
     ctx.actions.run(
         executable = deps_checker,
         arguments = [args],
-        inputs = depset(
-            jars_to_check,
-            transitive = [bootclasspath, full_classpath],
-        ),
+        inputs = depset(jars_to_check, transitive = [full_classpath]),
         outputs = [jdeps_output],
         mnemonic = "KtCheckStrictDeps" if enforce_strict_deps else "KtJdeps",
         progress_message = "%s deps for %s" % (
@@ -862,24 +853,13 @@
     if srcs or common_srcs or rule_family != _RULE_FAMILY.ANDROID_LIBRARY:
         deps.extend(kt_toolchain.kotlin_libs)
 
-    merged_deps = java_common.merge(deps + codegen_output_java_infos)
-
     # Skip srcs package check for android_library targets with no kotlin sources: b/239725424
     if rule_family != _RULE_FAMILY.ANDROID_LIBRARY or kt_srcs:
         _check_srcs_package(ctx.label.package, srcs, "srcs")
         _check_srcs_package(ctx.label.package, common_srcs, "common_srcs")
         _check_srcs_package(ctx.label.package, coverage_srcs, "coverage_srcs")
 
-    # Complete classpath including bootclasspath. Like for Javac, explicitly place direct
-    # compile_jars before transitive not to confuse strict_deps (b/149107867).
-    full_classpath = depset(
-        order = "preorder",
-        transitive = [
-            java_toolchain.bootclasspath,
-            merged_deps.compile_jars,
-            merged_deps.transitive_compile_time_jars,
-        ],
-    )
+    full_classpath = _create_classpath(java_toolchain, deps + codegen_output_java_infos)
 
     # Collect all plugin data, including processors to run and all plugin classpaths,
     # whether they have processors or not (b/120995492).
@@ -896,13 +876,13 @@
     out_jars = []
     out_srcjars = []
     out_compilejars = []
-    kapt_outputs = _EMPTY_KAPT_OUTPUTS
 
     # Kotlin compilation requires two passes when annotation processing is
     # required. The initial pass processes the annotations and generates
     # additional sources and the following pass compiles the Kotlin code.
     # Skip kapt if no plugins have processors (can happen with only
     # go/errorprone plugins, # b/110540324)
+    kapt_outputs = _EMPTY_KAPT_OUTPUTS
     if kt_srcs and plugin_processors:
         kapt_outputs = _kapt(
             ctx,
@@ -925,7 +905,6 @@
 
         out_jars.append(kapt_outputs.jar)
         java_syncer.add_srcjars([kapt_outputs.srcjar])
-        merged_deps = java_common.merge([merged_deps, kapt_outputs.java_info])
 
     kotlinc_result = None
     if kt_srcs or common_srcs:
@@ -952,13 +931,6 @@
         out_srcjars.append(kotlinc_result.source_jar)
         out_jars.append(kotlinc_result.output_jar)
 
-        # Add dep on JaCoCo runtime to merged_deps.
-        # The latter helps jdeps computation (b/130747644) but could be runtime-only if we computed
-        # compile-time Jdeps based using the compile Jar (which doesn't contain instrumentation).
-        # See b/117897097 for why it's still useful to make the (runtime) dep explicit.
-        if ctx.coverage_instrumented():
-            merged_deps = java_common.merge([merged_deps, kt_toolchain.coverage_runtime])
-
     classpath_resources_dirs, classpath_resources_non_dirs = _partition(
         classpath_resources,
         filter = lambda res: res.is_directory,
@@ -979,6 +951,17 @@
     java_genjar = None
     is_android_library_without_kt_srcs = rule_family == _RULE_FAMILY.ANDROID_LIBRARY and not kt_srcs
     if java_srcs or java_syncer.srcjars or classpath_resources:
+        javac_deps = deps + codegen_output_java_infos  # Defensive copy
+        if kapt_outputs.java_info:
+            javac_deps.append(kapt_outputs.java_info)
+        if kotlinc_result:
+            javac_deps.append(kotlinc_result.java_info)
+            if ctx.coverage_instrumented():
+                # Including the coverage runtime improves jdeps computation (b/130747644), but it
+                # could be runtime-only if we computed compile-time jdeps using the compile JAR
+                # (which doesn't contain instrumentation). See b/117897097.
+                javac_deps.append(kt_toolchain.coverage_runtime)
+
         javac_out = output if is_android_library_without_kt_srcs else file_factory.declare_file("-java.jar")
         javac_java_info = java_common.compile(
             ctx,
@@ -990,7 +973,7 @@
             exports = exports if is_android_library_without_kt_srcs else [],
             output = javac_out,
             exported_plugins = exported_plugins,
-            deps = ([kotlinc_result.java_info] if kotlinc_result else []) + [merged_deps],
+            deps = javac_deps,
             # Include default_javac_flags, which reflect Blaze's --javacopt flag, so they win over
             # all sources of default flags (for Ellipsis builds, see b/125452475).
             # TODO: remove default_javac_flags here once java_common.compile is fixed.
@@ -1182,6 +1165,17 @@
     """Collects the requested provider from the given list of deps."""
     return [dep[provider] for dep in deps if provider in dep]
 
+def _create_classpath(java_toolchain, deps):
+    # To not confuse strictdeps, order as boot > direct > transitive JARs (b/149107867).
+    return depset(
+        order = "preorder",
+        transitive = (
+            [java_toolchain.bootclasspath] +
+            [dep.compile_jars for dep in deps] +
+            [dep.transitive_compile_time_jars for dep in deps]
+        ),
+    )
+
 def _partition(sequence, filter):
     pos, neg = [], []
     for element in sequence:
diff --git a/kotlin/jvm_library.internal.bzl b/kotlin/jvm_library.internal.bzl
index be9243d..85b9e52 100644
--- a/kotlin/jvm_library.internal.bzl
+++ b/kotlin/jvm_library.internal.bzl
@@ -64,7 +64,7 @@
         exports = ctx.attr.exports,
         javacopts = ctx.attr.javacopts,
         kotlincopts = merge_kotlincopts(ctx),
-        neverlink = False,
+        neverlink = ctx.attr.neverlink,
         testonly = ctx.attr.testonly,
                 android_lint_plugins = ctx.attr._android_lint_plugins,
         manifest = None,
@@ -187,6 +187,11 @@
                      if `.java` `srcs` are provided or annotation processors generate sources for this
                      rule.""",
     ),
+    neverlink = attr.bool(
+        default = False,
+        doc = """Only use this library for compilation and not at runtime. Useful if the library
+                  will be provided by the runtime environment during execution.""",
+    ),
     plugins = attr.label_list(
         providers = [
             [JavaPluginInfo],
diff --git a/tests/analysis/BUILD b/tests/analysis/BUILD
index b927805..0533e13 100644
--- a/tests/analysis/BUILD
+++ b/tests/analysis/BUILD
@@ -17,6 +17,7 @@
 load("//tests/analysis:jvm_compile_test.bzl", jvm_compile_test_suite = "test_suite")
 load("//tests/analysis:jvm_import_test.bzl", jvm_import_test_suite = "test_suite")
 load("//tests/analysis:jvm_library_test.bzl", jvm_library_test_suite = "test_suite")
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
 
 licenses(["notice"])
 
diff --git a/tests/analysis/for_test.bzl b/tests/analysis/for_test.bzl
new file mode 100644
index 0000000..434c1a4
--- /dev/null
+++ b/tests/analysis/for_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.
+
+"""Rules for test."""
+
+load("//kotlin:jvm_library.bzl", "kt_jvm_library")
+load("//tests/analysis:util.bzl", "ONLY_FOR_ANALYSIS_TEST_TAGS")
+
+def _kt_jvm_library_for_test(name, **kwargs):
+    kt_jvm_library(
+        name = name,
+        tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
+        **kwargs
+    )
+    return name
+
+def _java_library_for_test(name, **kwargs):
+    native.java_library(
+        name = name,
+        tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
+        **kwargs
+    )
+    return name
+
+rules_for_test = struct(
+    kt_jvm_library = _kt_jvm_library_for_test,
+    java_library = _java_library_for_test,
+)
diff --git a/tests/analysis/jvm_library/data/BUILD b/tests/analysis/jvm_library/data/BUILD
new file mode 100644
index 0000000..1809aa1
--- /dev/null
+++ b/tests/analysis/jvm_library/data/BUILD
@@ -0,0 +1,40 @@
+# 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("//tests/analysis:for_test.bzl", "rules_for_test")
+load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test")
+
+package(default_testonly = True)
+
+licenses(["notice"])
+
+jvm_library_test(
+    name = "data_test",
+    expected = dict(
+        data = [
+            "data.txt",
+            # libX.jar is always in data_runfiles as well - just append it.
+            "libdata.jar",
+        ],
+    ),
+    target_under_test = rules_for_test.kt_jvm_library(
+        name = "data",
+        srcs = [
+            "Input.kt",
+        ],
+        data = [
+            "data.txt",
+        ],
+    ),
+)
diff --git a/tests/analysis/jvm_library/data/Input.kt b/tests/analysis/jvm_library/data/Input.kt
new file mode 100644
index 0000000..e675bc1
--- /dev/null
+++ b/tests/analysis/jvm_library/data/Input.kt
@@ -0,0 +1,16 @@
+/*
+ * * 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.
+ */
+
diff --git a/tests/analysis/jvm_library/data/data.txt b/tests/analysis/jvm_library/data/data.txt
new file mode 100644
index 0000000..e3ba5e8
--- /dev/null
+++ b/tests/analysis/jvm_library/data/data.txt
@@ -0,0 +1,13 @@
+# 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.
\ No newline at end of file
diff --git a/tests/analysis/jvm_library/deps/BUILD b/tests/analysis/jvm_library/deps/BUILD
new file mode 100644
index 0000000..ccb03a0
--- /dev/null
+++ b/tests/analysis/jvm_library/deps/BUILD
@@ -0,0 +1,48 @@
+# 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("//tests/analysis:for_test.bzl", "rules_for_test")
+load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test")
+
+package(default_testonly = True)
+
+licenses(["notice"])
+
+rules_for_test.kt_jvm_library(
+    name = "deps_test_kt_dep",
+    srcs = [
+        "Input.kt",
+    ],
+)
+
+rules_for_test.java_library(
+    name = "deps_test_java_dep",
+    srcs = [
+        "Input.java",
+    ],
+)
+
+jvm_library_test(
+    name = "deps_test",
+    target_under_test = rules_for_test.kt_jvm_library(
+        name = "deps",
+        srcs = [
+            "Foo.java",
+        ],
+        deps = [
+            ":deps_test_java_dep",
+            ":deps_test_kt_dep",
+        ],
+    ),
+)
diff --git a/tests/analysis/jvm_library/deps/Foo.java b/tests/analysis/jvm_library/deps/Foo.java
new file mode 100644
index 0000000..e675bc1
--- /dev/null
+++ b/tests/analysis/jvm_library/deps/Foo.java
@@ -0,0 +1,16 @@
+/*
+ * * 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.
+ */
+
diff --git a/tests/analysis/jvm_library/deps/Input.java b/tests/analysis/jvm_library/deps/Input.java
new file mode 100644
index 0000000..e675bc1
--- /dev/null
+++ b/tests/analysis/jvm_library/deps/Input.java
@@ -0,0 +1,16 @@
+/*
+ * * 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.
+ */
+
diff --git a/tests/analysis/jvm_library/deps/Input.kt b/tests/analysis/jvm_library/deps/Input.kt
new file mode 100644
index 0000000..e675bc1
--- /dev/null
+++ b/tests/analysis/jvm_library/deps/Input.kt
@@ -0,0 +1,16 @@
+/*
+ * * 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.
+ */
+
diff --git a/tests/analysis/jvm_library/friends/BUILD b/tests/analysis/jvm_library/friends/BUILD
index 707b589..538bdce 100644
--- a/tests/analysis/jvm_library/friends/BUILD
+++ b/tests/analysis/jvm_library/friends/BUILD
@@ -13,7 +13,8 @@
 # limitations under the License.
 
 load("//kotlin:rules.bzl", "kt_jvm_library")
-load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test", "kt_jvm_library_under_test")
+load("//tests/analysis:for_test.bzl", "rules_for_test")
+load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test")
 load("//tests/analysis:util.bzl", "ONLY_FOR_ANALYSIS_TEST_TAGS")
 
 package(
@@ -26,7 +27,7 @@
 jvm_library_test(
     name = "no_kt_exported_friend_cross_package_test",
     expected_friend_jar_names = [],
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "no_kt_exported_friend_cross_package",
         srcs = ["Input.kt"],
         deps = [
@@ -42,7 +43,7 @@
         "libjava_exports_friend-hjar.jar",
         "libfriend-compile.jar",
     ],
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "has_java_exported_friend_in_package",
         srcs = ["Input.kt"],
         deps = [":java_exports_friend"],
@@ -55,7 +56,7 @@
         "libkt_exports_friend-compile.jar",
         "libfriend-compile.jar",
     ],
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "has_kt_exported_friend_in_package",
         srcs = ["Input.kt"],
         deps = [":kt_exports_friend"],
@@ -65,7 +66,7 @@
 jvm_library_test(
     name = "no_direct_friend_testing_package_test",
     expected_friend_jar_names = [],
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "no_direct_friend_testing_package",
         srcs = ["Input.kt"],
         deps = ["//tests/analysis/jvm_library/friends/testing:testingfriend"],
@@ -75,7 +76,7 @@
 jvm_library_test(
     name = "no_direct_friend_subpackage_test",
     expected_friend_jar_names = [],
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "no_direct_friend_subpackage",
         srcs = ["Input.kt"],
         deps = ["//tests/analysis/jvm_library/friends/sub:subfriend"],
@@ -85,7 +86,7 @@
 jvm_library_test(
     name = "has_direct_friend_in_package_test",
     expected_friend_jar_names = ["libfriend-compile.jar"],
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "has_direct_friend_in_package",
         srcs = ["Input.kt"],
         deps = [":friend"],
diff --git a/tests/analysis/jvm_library/friends/sub/BUILD b/tests/analysis/jvm_library/friends/sub/BUILD
index 3a77ed3..e7c619f 100644
--- a/tests/analysis/jvm_library/friends/sub/BUILD
+++ b/tests/analysis/jvm_library/friends/sub/BUILD
@@ -13,7 +13,8 @@
 # limitations under the License.
 
 load("//kotlin:rules.bzl", "kt_jvm_library")
-load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test", "kt_jvm_library_under_test")
+load("//tests/analysis:for_test.bzl", "rules_for_test")
+load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test")
 load("//tests/analysis:util.bzl", "ONLY_FOR_ANALYSIS_TEST_TAGS")
 
 package(
@@ -29,7 +30,7 @@
         "libkt_exports_friend-compile.jar",
         # Absent # "libfriend-compile.jar"
     ],
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "no_kt_exported_friend_cross_package",
         srcs = ["Input.kt"],
         deps = [":kt_exports_friend"],
@@ -39,7 +40,7 @@
 jvm_library_test(
     name = "no_direct_friend_cross_package_test",
     expected_friend_jar_names = [],
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "no_direct_friend_cross_package",
         srcs = ["Input.kt"],
         deps = ["//tests/analysis/jvm_library/friends:friend"],
diff --git a/tests/analysis/jvm_library/friends/testing/BUILD b/tests/analysis/jvm_library/friends/testing/BUILD
index 8f08a3d..827aa30 100644
--- a/tests/analysis/jvm_library/friends/testing/BUILD
+++ b/tests/analysis/jvm_library/friends/testing/BUILD
@@ -13,7 +13,8 @@
 # limitations under the License.
 
 load("//kotlin:rules.bzl", "kt_jvm_library")
-load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test", "kt_jvm_library_under_test")
+load("//tests/analysis:for_test.bzl", "rules_for_test")
+load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test")
 load("//tests/analysis:util.bzl", "ONLY_FOR_ANALYSIS_TEST_TAGS")
 
 package(
@@ -29,7 +30,7 @@
         "libkt_exports_friend-compile.jar",
         "libfriend-compile.jar",
     ],
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "has_kt_exported_friend_impl_package",
         srcs = ["Input.kt"],
         deps = [":kt_exports_friend"],
@@ -41,7 +42,7 @@
     expected_friend_jar_names = [
         "libfriend-compile.jar",
     ],
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "has_direct_friend_impl_package",
         srcs = ["Input.kt"],
         deps = ["//tests/analysis/jvm_library/friends:friend"],
@@ -54,7 +55,7 @@
         "libkt_exports_subfriend-compile.jar",
         # Absent # "subfriend-compile.jar"
     ],
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "no_kt_exported_friend_sibling_package",
         srcs = ["Input.kt"],
         deps = [":kt_exports_subfriend"],
@@ -64,7 +65,7 @@
 jvm_library_test(
     name = "no_direct_friend_sibling_package_test",
     expected_friend_jar_names = [],
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "no_direct_friend_sibling_package",
         srcs = ["Input.kt"],
         deps = ["//tests/analysis/jvm_library/friends/sub:subfriend"],
diff --git a/tests/analysis/jvm_library/no_java_srcs/BUILD b/tests/analysis/jvm_library/no_java_srcs/BUILD
index c7a1144..116dcfd 100644
--- a/tests/analysis/jvm_library/no_java_srcs/BUILD
+++ b/tests/analysis/jvm_library/no_java_srcs/BUILD
@@ -12,7 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test", "kt_jvm_library_under_test")
+load("//tests/analysis:for_test.bzl", "rules_for_test")
+load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test")
 
 package(default_testonly = True)
 
@@ -20,7 +21,7 @@
 
 jvm_library_test(
     name = "no_java_srcs_test",
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "no_java_srcs",
         srcs = [
             "Input.kt",
diff --git a/tests/analysis/jvm_library/no_kt_srcs/BUILD b/tests/analysis/jvm_library/no_kt_srcs/BUILD
index a61492c..a6e4f18 100644
--- a/tests/analysis/jvm_library/no_kt_srcs/BUILD
+++ b/tests/analysis/jvm_library/no_kt_srcs/BUILD
@@ -12,7 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test", "kt_jvm_library_under_test")
+load("//tests/analysis:for_test.bzl", "rules_for_test")
+load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test")
 
 package(default_testonly = True)
 
@@ -20,7 +21,7 @@
 
 jvm_library_test(
     name = "no_kt_srcs_test",
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "no_kt_srcs",
         srcs = [
             "Input.java",
diff --git a/tests/analysis/jvm_library/nodeps/BUILD b/tests/analysis/jvm_library/nodeps/BUILD
index b8e96d7..fc3e673 100644
--- a/tests/analysis/jvm_library/nodeps/BUILD
+++ b/tests/analysis/jvm_library/nodeps/BUILD
@@ -12,7 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test", "kt_jvm_library_under_test")
+load("//tests/analysis:for_test.bzl", "rules_for_test")
+load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test")
 
 package(default_testonly = True)
 
@@ -20,7 +21,7 @@
 
 jvm_library_test(
     name = "nodeps_test",
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "nodeps",
         srcs = [
             "Input.java",
diff --git a/tests/analysis/jvm_library/only_common_srcs/BUILD b/tests/analysis/jvm_library/only_common_srcs/BUILD
index a893003..49930f2 100644
--- a/tests/analysis/jvm_library/only_common_srcs/BUILD
+++ b/tests/analysis/jvm_library/only_common_srcs/BUILD
@@ -12,7 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test", "kt_jvm_library_under_test")
+load("//tests/analysis:for_test.bzl", "rules_for_test")
+load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test")
 
 package(default_testonly = True)
 
@@ -20,7 +21,7 @@
 
 jvm_library_test(
     name = "only_common_srcs_test",
-    target_under_test = kt_jvm_library_under_test(
+    target_under_test = rules_for_test.kt_jvm_library(
         name = "only_common_srcs",
         common_srcs = [
             "Input.kt",
diff --git a/tests/analysis/jvm_library/runtime_deps/BUILD b/tests/analysis/jvm_library/runtime_deps/BUILD
new file mode 100644
index 0000000..17457ba
--- /dev/null
+++ b/tests/analysis/jvm_library/runtime_deps/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("//tests/analysis:for_test.bzl", "rules_for_test")
+load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test")
+
+package(default_testonly = True)
+
+licenses(["notice"])
+
+rules_for_test.java_library(
+    name = "runtime_deps_test_dep",
+    srcs = [],
+)
+
+jvm_library_test(
+    name = "runtime_deps_test",
+    target_under_test = rules_for_test.kt_jvm_library(
+        name = "runtime_deps",
+        srcs = [
+            "Input.kt",
+        ],
+        runtime_deps = [
+            ":runtime_deps_test_dep",
+        ],
+    ),
+)
diff --git a/tests/analysis/jvm_library/runtime_deps/Input.java b/tests/analysis/jvm_library/runtime_deps/Input.java
new file mode 100644
index 0000000..e675bc1
--- /dev/null
+++ b/tests/analysis/jvm_library/runtime_deps/Input.java
@@ -0,0 +1,16 @@
+/*
+ * * 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.
+ */
+
diff --git a/tests/analysis/jvm_library/runtime_deps/Input.kt b/tests/analysis/jvm_library/runtime_deps/Input.kt
new file mode 100644
index 0000000..e675bc1
--- /dev/null
+++ b/tests/analysis/jvm_library/runtime_deps/Input.kt
@@ -0,0 +1,16 @@
+/*
+ * * 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.
+ */
+
diff --git a/tests/analysis/jvm_library_test.bzl b/tests/analysis/jvm_library_test.bzl
index 684cb92..6435cc5 100644
--- a/tests/analysis/jvm_library_test.bzl
+++ b/tests/analysis/jvm_library_test.bzl
@@ -89,6 +89,13 @@
         friend_jar_names = [p.rsplit("/", 1)[1] for p in friend_paths_arg.split(",")] if friend_paths_arg else []
         asserts.set_equals(env, sets.make(ctx.attr.expected_friend_jar_names), sets.make(friend_jar_names))
 
+    asserts.equals(
+        env,
+        ctx.attr.expect_neverlink,
+        len(actual[JavaInfo].transitive_runtime_jars.to_list()) == 0,
+        "Mismatch: Expected transitive_runtime_jars iff (neverlink == False)",
+    )
+
     return analysistest.end(env)
 
 _test = analysistest.make(
@@ -107,19 +114,12 @@
             default = _DEFAULT_LIST,
         ),
         expect_processor_classpath = attr.bool(),
+        expect_neverlink = attr.bool(),
     ),
 )
 
 jvm_library_test = _test
 
-def kt_jvm_library_under_test(name, **kwargs):
-    kt_jvm_library(
-        name = name,
-        tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
-        **kwargs
-    )
-    return name
-
 def _coverage_test_impl(ctx):
     env = analysistest.begin(ctx)
     target_under_test = analysistest.target_under_test(env)
@@ -147,77 +147,6 @@
 def _extract_data_runfiles(target):
     return [f.basename for f in target[DefaultInfo].data_runfiles.files.to_list()]
 
-def _test_kt_jvm_library_with_deps():
-    test_name = "kt_jvm_library_with_deps_test"
-
-    kt_jvm_library(
-        name = test_name + "_kt_dep",
-        srcs = [create_file(
-            name = test_name + "/Hello.kt",
-            content = """
-package test
-
-fun hello(): String = "Hello!"
-""",
-        )],
-    )
-    native.java_library(
-        name = test_name + "_java_dep",
-        srcs = ["testinputs/Foo.java"],
-    )
-    kt_jvm_library(
-        name = test_name + "_tut",
-        srcs = [
-            create_file(
-                name = test_name + "/Hi.kt",
-                content = """
-package test
-
-fun hi(): String = "Hi!"
-""",
-            ),
-            "testinputs/Bar.java",
-        ],
-        deps = [
-            test_name + "_kt_dep",
-            test_name + "_java_dep",
-        ],
-    )
-    _test(
-        name = test_name,
-        target_under_test = test_name + "_tut",
-    )
-    return test_name
-
-def _test_kt_jvm_library_with_runtime_deps():
-    test_name = "kt_jvm_library_with_runtime_deps_test"
-    create_file(
-        name = test_name + "/Salutations.kt",
-        content = """
-package test
-
-fun greeting(): String = "Hello World!"
-""",
-    )
-    native.java_library(
-        name = test_name + "_dep",
-        srcs = [],
-    )
-    kt_jvm_library(
-        name = test_name + "_tut",
-        srcs = [
-            test_name + "/Salutations.kt",
-        ],
-        runtime_deps = [
-            test_name + "_dep",
-        ],
-    )
-    _test(
-        name = test_name,
-        target_under_test = test_name + "_tut",
-    )
-    return test_name
-
 def _test_kt_jvm_library_with_proguard_specs():
     test_name = "kt_jvm_library_with_proguard_specs_test"
     create_file(
@@ -283,48 +212,6 @@
     )
     return test_name
 
-def _test_kt_jvm_library_with_data():
-    test_name = "kt_jvm_library_with_data_test"
-    kt_jvm_lib_name = test_name + "_tut"
-
-    data_txt = create_file(
-        name = test_name + "data.txt",
-        content = """
-Hello World!
-""",
-    )
-
-    # Kotlin file
-    muchdata_kt = create_file(
-        name = test_name + "/MuchData.kt",
-        content = """
-package test
-
-import java.io.File
-
-fun greeting(): String = File("data.txt").readText()
-""",
-    )
-
-    kt_jvm_library(
-        name = kt_jvm_lib_name,
-        srcs = [muchdata_kt],
-        data = [data_txt],
-    )
-
-    _test(
-        name = test_name,
-        target_under_test = kt_jvm_lib_name,
-        expected = dict(
-            data = [
-                data_txt,
-                # libX.jar is always in data_runfiles as well - just append it.
-                "lib%s.jar" % kt_jvm_lib_name,
-            ],
-        ),
-    )
-    return test_name
-
 def _test_kt_jvm_library_with_plugin():
     test_name = "kt_jvm_library_with_plugin_test"
     create_file(
@@ -744,8 +631,6 @@
             _test_kt_jvm_library_dep_on_exported_plugin(),
             _test_kt_jvm_library_java_dep_on_exported_plugin(),
             _test_kt_jvm_library_no_kt_srcs_with_plugin(),
-            _test_kt_jvm_library_with_data(),
-            _test_kt_jvm_library_with_deps(),
             _test_kt_jvm_library_with_export_that_exports_plugin(),
             _test_kt_jvm_library_with_exported_plugin(),
             _test_kt_jvm_library_with_exports(),
@@ -755,7 +640,6 @@
             _test_kt_jvm_library_with_plugin(),
             _test_kt_jvm_library_with_proguard_specs(),
             _test_kt_jvm_library_with_resources(),
-            _test_kt_jvm_library_with_runtime_deps(),
             _test_kt_jvm_library_coverage(),
         ],
     )
diff --git a/tests/jvm/java/neverlink/BUILD b/tests/jvm/java/neverlink/BUILD
new file mode 100644
index 0000000..c6daa08
--- /dev/null
+++ b/tests/jvm/java/neverlink/BUILD
@@ -0,0 +1,28 @@
+# 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("//tests/analysis:for_test.bzl", "rules_for_test")
+load("//tests/analysis:jvm_library_test.bzl", "jvm_library_test")
+
+licenses(["notice"])
+
+jvm_library_test(
+    name = "neverlinked_input_library_test",
+    expect_neverlink = True,
+    target_under_test = rules_for_test.kt_jvm_library(
+        name = "neverlinked_input_library",
+        srcs = ["Input.kt"],
+        neverlink = True,
+    ),
+)
diff --git a/tests/jvm/java/neverlink/Input.kt b/tests/jvm/java/neverlink/Input.kt
new file mode 100644
index 0000000..e675bc1
--- /dev/null
+++ b/tests/jvm/java/neverlink/Input.kt
@@ -0,0 +1,16 @@
+/*
+ * * 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.
+ */
+