Snap for 9550355 from bf16c560ee1e97cde64a35348ee50bf580ccac12 to sdk-release
Change-Id: I200bbf7986e3ca8cbe3c1cd320dd70d9187f1b07
diff --git a/METADATA b/METADATA
index 5d59256..9e9632a 100644
--- a/METADATA
+++ b/METADATA
@@ -11,8 +11,8 @@
type: GIT
value: "https://team.googlesource.com/kotlin-rules/rules"
}
- version: "aebca278376b63c9c07296c9aa052845e0c1fe2a"
- last_upgrade_date { year: 2022 month: 9 day: 7 }
+ version: "0904db290987a7e48a708369e5093b6d033769e7"
+ last_upgrade_date { year: 2022 month: 12 day: 14}
license_type: NOTICE
}
diff --git a/WORKSPACE b/WORKSPACE
index 12281f1..5d01cdd 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -70,7 +70,7 @@
http_archive(
name = "kotlinc",
build_file = "@//bazel:kotlinc.BUILD",
- sha256 = "7683f5451ef308eb773a686ee7779a76a95ed8b143c69ac247937619d7ca3a09",
+ sha256 = "8412b31b808755f0c0d336dbb8c8443fa239bf32ddb3cdb81b305b25f0ad279e",
strip_prefix = "kotlinc",
urls = [
"https://github.com/JetBrains/kotlin/releases/download/v{0}/kotlin-compiler-{0}.zip".format(KT_VERSION[1:].replace("_", ".")),
@@ -86,6 +86,7 @@
"com.google.auto.value:auto-value:1.9",
"com.google.testing.compile:compile-testing:0.19",
"com.google.truth:truth:1.1.3",
+ "info.picocli:picocli:4.6.3",
"javax.inject:jsr330-api:0.9",
"junit:junit:4.13.2",
"org.jacoco:org.jacoco.agent:0.8.8",
diff --git a/bazel/BUILD b/bazel/BUILD
index e10757f..cc77038 100644
--- a/bazel/BUILD
+++ b/bazel/BUILD
@@ -38,5 +38,8 @@
java_binary(
name = "jacoco_cli",
main_class = "org.jacoco.cli.internal.Main",
- runtime_deps = ["@maven//:org_jacoco_org_jacoco_cli"],
+ runtime_deps = [
+ "@bazel_tools//tools/jdk:JacocoCoverage",
+ "@maven//:org_jacoco_org_jacoco_cli",
+ ],
)
diff --git a/bazel/deploy_jar_freshness_golden_test.bzl b/bazel/deploy_jar_freshness_golden_test.bzl
new file mode 100644
index 0000000..9e36132
--- /dev/null
+++ b/bazel/deploy_jar_freshness_golden_test.bzl
@@ -0,0 +1,58 @@
+# 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.
+
+"""Test on *_deploy.jar freshness"""
+
+def _deploy_jar_freshness_golden_test_impl(ctx):
+ test_command = """
+ if ! cmp $1 $2 ; then
+ echo "$1 needs to be rebuilt"
+ echo "exit 1" > $3
+ exit 0
+ fi
+
+ # Always passes
+ echo "#!/bin/bash" > $3
+ """
+
+ dummy_test_script = ctx.actions.declare_file(ctx.label.name + ".sh")
+ ctx.actions.run_shell(
+ inputs = [ctx.file.current_jar, ctx.file.newly_built_jar],
+ outputs = [dummy_test_script],
+ arguments = [
+ ctx.file.current_jar.path,
+ ctx.file.newly_built_jar.path,
+ dummy_test_script.path,
+ ],
+ command = test_command,
+ )
+
+ return [DefaultInfo(executable = dummy_test_script)]
+
+deploy_jar_freshness_golden_test = rule(
+ implementation = _deploy_jar_freshness_golden_test_impl,
+ attrs = dict(
+ newly_built_jar = attr.label(
+ doc = "Newly built target deploy.jar",
+ mandatory = True,
+ allow_single_file = [".jar"],
+ ),
+ current_jar = attr.label(
+ doc = "Prebuilt jar to verify",
+ allow_single_file = [".jar"],
+ mandatory = True,
+ ),
+ ),
+ test = True,
+)
diff --git a/bazel/stubs.bzl b/bazel/stubs.bzl
index d948cc8..95f5b87 100644
--- a/bazel/stubs.bzl
+++ b/bazel/stubs.bzl
@@ -32,3 +32,6 @@
]
BASE_JVMOPTS = []
+
+def select_java_language_version(**_kwargs):
+ return "11"
diff --git a/kokoro/presubmit.sh b/kokoro/presubmit.sh
index 716cb86..c6302a3 100755
--- a/kokoro/presubmit.sh
+++ b/kokoro/presubmit.sh
@@ -37,18 +37,19 @@
mkdir -p "$hsperfdata_dir"
cd "${workspace_root}"
-"$bazel" test \
+# Run test coverage for all the test targets except excluded by
+# --instrumentation_filter - code coverage doesn't work for them and they
+# would only be tested
+"$bazel" coverage \
--sandbox_tmpfs_path="$hsperfdata_dir" \
--verbose_failures \
--experimental_google_legacy_api \
+ --instrumentation_filter=-//tests/jvm/java/multijarimport[/:],-//tests/jvm/java/functions[/:] \
//tests/...
-# Testing with code coverage
+# For a specific test //tools:source_jar_zipper_freshness_test run test only
"$bazel" test \
--sandbox_tmpfs_path="$hsperfdata_dir" \
--verbose_failures \
--experimental_google_legacy_api \
- --collect_code_coverage=1 \
- //tests/analysis:kt_jvm_compile_using_kt_jvm_compile_with_r_java_test \
- //tests/analysis:kt_jvm_compile_with_r_java_as_first_dep_test \
- //tests/analysis:kt_jvm_compile_without_srcs_and_with_exports_test
\ No newline at end of file
+ //tools:source_jar_zipper_freshness_test
\ No newline at end of file
diff --git a/kotlin/common.bzl b/kotlin/common.bzl
index 3ffc660..3789b0c 100644
--- a/kotlin/common.bzl
+++ b/kotlin/common.bzl
@@ -15,9 +15,9 @@
"""Common Kotlin definitions."""
load("@bazel_skylib//lib:sets.bzl", "sets")
-load("@bazel_skylib//lib:structs.bzl", "structs")
load("//bazel:stubs.bzl", "BASE_JVMOPTS")
load("//bazel:stubs.bzl", "DEFAULT_BUILTIN_PROCESSORS")
+load(":file_factory.bzl", "FileFactory")
# TODO: Remove the _ALLOWED_*_RULES lists to determine which rules
# are accepted dependencies to Kotlin rules as the approach does not scale
@@ -42,6 +42,7 @@
"java_proto_library",
"java_wrap_cc", # b/152799927
"jvm_import",
+ "_kmp_library",
"kt_grpc_library_helper",
"kt_jvm_library_helper",
"kt_jvm_import",
@@ -106,6 +107,7 @@
# Runs KAPT in two separate actions so annotation processors only rerun when Kotlin stubs changed.
def _kapt(
ctx,
+ file_factory,
kt_srcs = [],
common_srcs = [],
java_srcs = [],
@@ -124,7 +126,7 @@
# just run turbine if there are no .kt sources.
stub_srcjars = []
if kt_srcs or common_srcs:
- stubs_dir = ctx.actions.declare_directory(ctx.label.name + "/kapt/gen/stubs")
+ stubs_dir = file_factory.declare_directory("/kapt/gen/stubs")
_kapt_stubs(
ctx,
stubs_dir,
@@ -142,15 +144,15 @@
# mostly to filter out non-.java stub outputs, e.g. .kapt_metadata.
stub_srcjars.append(_create_jar(
ctx,
- toolchain.jar_tool,
- ctx.actions.declare_file("stubs-srcjar.jar", sibling = stubs_dir),
- [stubs_dir],
- file_extensions = ["java"],
+ toolchain,
+ file_factory.declare_file("stubs-srcjar.jar"),
+ kt_inputs = [stubs_dir],
+ ignore_not_allowed_files = True,
))
- output_jar = ctx.actions.declare_file(ctx.label.name + "-kapt.jar")
- output_srcjar = ctx.actions.declare_file(ctx.label.name + "-kapt.srcjar")
- output_manifest = ctx.actions.declare_file(ctx.label.name + "-kapt.jar_manifest_proto")
+ output_jar = file_factory.declare_file("-kapt.jar")
+ output_srcjar = file_factory.declare_file("-kapt.srcjar")
+ output_manifest = file_factory.declare_file("-kapt.jar_manifest_proto")
_run_turbine(
ctx,
toolchain,
@@ -170,8 +172,19 @@
jar = output_jar,
manifest = output_manifest,
srcjar = output_srcjar,
+ java_info = JavaInfo(
+ output_jar = output_jar,
+ compile_jar = output_jar,
+ ),
)
+_EMPTY_KAPT_OUTPUTS = struct(
+ jar = None,
+ manifest = None,
+ srcjar = None,
+ java_info = None,
+)
+
def _kapt_stubs(
ctx,
stubs_dir,
@@ -303,9 +316,12 @@
progress_message = progress_message,
)
else:
+ java_runtime = toolchain.turbine_java_runtime
+ if not java_runtime:
+ java_runtime = toolchain.java_runtime
_actions_run_deploy_jar(
ctx = ctx,
- java_runtime = toolchain.java_runtime,
+ java_runtime = java_runtime,
deploy_jar = toolchain.turbine,
deploy_jsa = toolchain.turbine_jsa,
inputs = inputs,
@@ -332,7 +348,7 @@
# Run GenClass tool to derive gen_class_jar by filtering hand-written sources.
# cf. Bazel's JavaCompilationHelper#createGenJarAction
- result = ctx.actions.declare_file(ctx.label.name + "-gen.jar")
+ result = FileFactory(ctx, javac_jar).declare_file("-gen.jar")
genclass_args = ctx.actions.args()
genclass_args.add("--manifest_proto", manifest_proto)
@@ -368,9 +384,10 @@
def _run_kotlinc(
ctx,
- output,
+ file_factory,
kt_srcs = [],
common_srcs = [],
+ coverage_srcs = [],
java_srcs_and_dirs = [],
kotlincopts = [],
compile_jdeps = depset(),
@@ -381,9 +398,6 @@
friend_jars = depset(),
enforce_strict_deps = False,
enforce_complete_jdeps = False):
- if output.extension != "jar":
- fail("Expect to output a Jar but got %s" % output)
-
direct_inputs = []
transitive_inputs = []
outputs = []
@@ -403,7 +417,7 @@
kotlinc_args.add(toolchain.jvm_abi_gen_plugin, format = "-Xplugin=%s")
direct_inputs.append(toolchain.jvm_abi_gen_plugin)
- kt_ijar = ctx.actions.declare_file(output.basename[:-4] + "-ijar.jar", sibling = output)
+ kt_ijar = file_factory.declare_file("-ijar.jar")
kotlinc_args.add("-P", kt_ijar, format = "plugin:org.jetbrains.kotlin.jvm.abi:outputDir=%s")
outputs.append(kt_ijar)
@@ -419,6 +433,7 @@
kotlinc_args.add_all(common_srcs, format_each = "-Xcommon-sources=%s")
direct_inputs.extend(common_srcs)
+ output = file_factory.declare_file(".jar")
kotlinc_args.add("-d", output)
outputs.append(output)
kotlinc_args.add_all(kt_srcs)
@@ -451,29 +466,40 @@
},
)
- # TODO: Normalize paths to match package declarations in source files.
srcjar = _create_jar(
ctx,
- toolchain.jar_tool,
- ctx.actions.declare_file(ctx.label.name + "-kt-src.jar"),
- kt_srcs + common_srcs,
+ toolchain,
+ file_factory.declare_file("-kt-src.jar"),
+ kt_inputs = kt_srcs,
+ common_inputs = common_srcs,
)
- return struct(
+ if ctx.coverage_instrumented():
+ output = _offline_instrument_jar(
+ ctx,
+ toolchain,
+ output,
+ kt_srcs + common_srcs + coverage_srcs,
+ )
+
+ result = dict(
output_jar = output,
compile_jar = kt_ijar,
source_jar = srcjar,
)
+ return struct(java_info = JavaInfo(**result), **result)
def _get_original_kt_target_label(ctx):
label = ctx.label
if label.name.find("_DO_NOT_DEPEND") > 0:
# Remove rule suffix added by kt_android_library
label = label.relative(":%s" % label.name[0:label.name.find("_DO_NOT_DEPEND")])
-
+ elif hasattr(ctx.attr, "_kt_codegen_plugin_build_tool") and label.name.endswith("_processed_srcs"):
+ # Remove rule suffix added by kt_codegen_filegroup. b/259984258
+ label = label.relative(":{}".format(label.name.removesuffix("_processed_srcs")))
return label
-def _check_deps(
+def _run_import_deps_checker(
ctx,
jars_to_check = [],
merged_deps = None,
@@ -481,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" % (
@@ -517,27 +534,31 @@
)
def _offline_instrument_jar(ctx, toolchain, jar, srcs = []):
- paths_for_coverage_file = ctx.actions.declare_file(ctx.label.name + "-kt-paths-for-coverage.txt")
+ if not jar.basename.endswith(".jar"):
+ fail("Expect JAR input but got %s" % jar)
+ file_factory = FileFactory(ctx, jar)
+
+ paths_for_coverage_file = file_factory.declare_file("-kt-paths-for-coverage.txt")
paths = ctx.actions.args()
paths.set_param_file_format("multiline") # don't shell-quote, just list file names
paths.add_all([src for src in srcs if src.is_source])
ctx.actions.write(paths_for_coverage_file, paths)
- result = ctx.actions.declare_file(ctx.label.name + "-instrumented.jar")
+ output = file_factory.declare_file("-instrumented.jar")
args = ctx.actions.args()
args.add(jar)
- args.add(result)
+ args.add(output)
args.add(paths_for_coverage_file)
ctx.actions.run(
executable = toolchain.coverage_instrumenter,
arguments = [args],
inputs = [jar, paths_for_coverage_file],
- outputs = [result],
+ outputs = [output],
mnemonic = "KtJaCoCoInstrument",
progress_message = "Instrumenting Kotlin for coverage collection: %s" % _get_original_kt_target_label(ctx),
)
- return result
+ return output
def _singlejar(
ctx,
@@ -572,8 +593,8 @@
progress_message = "Merging %s: %s" % (content, label),
)
-def _merge_jdeps(ctx, kt_jvm_toolchain, jdeps_files, output_suffix = ""):
- merged_jdeps_file = ctx.actions.declare_file(ctx.label.name + output_suffix + ".jdeps")
+def _merge_jdeps(ctx, kt_jvm_toolchain, jdeps_files, file_factory):
+ merged_jdeps_file = file_factory.declare_file("-merged.jdeps")
args = ctx.actions.args()
args.add("--kind=jdeps")
@@ -592,40 +613,46 @@
return merged_jdeps_file
-def _expand_zip(ctx, dir, input, extra_args = []):
- ctx.actions.run_shell(
- outputs = [dir],
+def _expand_zip(ctx, toolchain, dir, input):
+ args = ctx.actions.args()
+ args.add("unzip", input)
+ args.add(dir.path)
+
+ _actions_run_deploy_jar(
+ ctx = ctx,
+ java_runtime = toolchain.java_runtime,
+ deploy_jar = toolchain.source_jar_zipper,
inputs = [input],
- command = "unzip -q {input} -d {dir} {args} 2> /dev/null || mkdir -p {dir}".format(
- input = input.path,
- dir = dir.path,
- args = " ".join(extra_args),
- ),
+ outputs = [dir],
+ args = [args],
+ mnemonic = "SrcJarUnzip",
)
+
return dir
-def _create_jar(ctx, jar_tool, out_jar, inputs, file_extensions = None):
- def file_filter(file):
- return file.path if (
- file_extensions == None or (file.extension in file_extensions)
- ) else None
-
+def _create_jar(ctx, toolchain, out_jar, kt_inputs = [], common_inputs = [], ignore_not_allowed_files = False):
args = ctx.actions.args()
- args.add("cf", out_jar)
- args.add_all(inputs, map_each = file_filter, allow_closure = True)
+ args.add("zip")
+ args.add(out_jar)
+ args.add_joined("--kotlin_srcs", kt_inputs, join_with = ",")
+ args.add_joined("--common_srcs", common_inputs, join_with = ",")
+ if ignore_not_allowed_files:
+ args.add("-i")
- ctx.actions.run(
- executable = jar_tool,
- inputs = inputs,
+ _actions_run_deploy_jar(
+ ctx = ctx,
+ java_runtime = toolchain.java_runtime,
+ deploy_jar = toolchain.source_jar_zipper,
+ inputs = kt_inputs + common_inputs,
outputs = [out_jar],
- arguments = [args],
+ args = [args],
mnemonic = "KtJar",
progress_message = "Create Jar (kotlin/common.bzl): %{output}",
)
return out_jar
-def _create_jar_from_tree_artifacts(ctx, jar_tool, output_jar, input_dirs):
+def _create_jar_from_tree_artifacts(ctx, toolchain, output_jar, input_dirs):
"""Packs a sequence of tree artifacts into a single jar.
Given the following file directory structure,
@@ -645,11 +672,12 @@
"/usr/home/b/y",
],
then the blaze action would fail with an error message.
- "java.util.zip.ZipException: duplicate entry: 1.txt"
+ "java.lang.IllegalStateException: 1.txt has the same path as 1.txt!
+ If it is intended behavior rename one or both of them."
Args:
ctx: The build rule context.
- jar_tool: A Unix-API-compatible jar tool.
+ toolchain: Toolchain containing the jar tool.
output_jar: The jar to be produced by this action.
input_dirs: A sequence of tree artifacts to be zipped.
@@ -658,39 +686,30 @@
"""
args = ctx.actions.args()
+ args.add("zip_resources")
+ args.add(output_jar)
+ args.add_joined(
+ "--input_dirs",
+ input_dirs,
+ join_with = ",",
+ omit_if_empty = False,
+ expand_directories = False,
+ )
- for in_dir in input_dirs:
- if not in_dir.is_directory:
- fail("Expected a directory input, but got {}.".format(in_dir))
- args.add(in_dir.path)
-
- ctx.actions.run_shell(
- command = """
- JAR_TOOL={}
- OUT_JAR={}
- OUT_DIR="$(dirname $OUT_JAR)"
- RES_DIR=$OUT_DIR/META-INF
- mkdir $RES_DIR
- $JAR_TOOL cf $OUT_JAR -C $RES_DIR .
- rmdir $RES_DIR
- for INPUT_DIR in $@
- do
- if [ -d $INPUT_DIR ]
- then
- $JAR_TOOL uf $OUT_JAR -C $INPUT_DIR .
- fi
- done
- """.format(jar_tool.executable.path, output_jar.path),
- arguments = [args],
+ _actions_run_deploy_jar(
+ ctx = ctx,
+ java_runtime = toolchain.java_runtime,
+ deploy_jar = toolchain.source_jar_zipper,
inputs = input_dirs,
outputs = [output_jar],
- tools = [jar_tool],
+ args = [args],
mnemonic = "KtJarActionFromTreeArtifacts",
progress_message = "Create Jar %{output}",
)
+
return output_jar
-def _DirSrcjarSyncer(ctx, kt_toolchain, name):
+def _DirSrcjarSyncer(ctx, kt_toolchain, file_factory):
_dirs = []
_srcjars = []
@@ -702,10 +721,8 @@
_srcjars.append(
_create_jar_from_tree_artifacts(
ctx,
- kt_toolchain.jar_tool,
- ctx.actions.declare_file(
- "%s/%s%s.srcjar" % (ctx.label.name, name, len(_srcjars)),
- ),
+ kt_toolchain,
+ file_factory.declare_file("%s.srcjar" % len(_srcjars)),
dirs,
),
)
@@ -718,11 +735,9 @@
_dirs.append(
_expand_zip(
ctx,
- ctx.actions.declare_directory(
- "%s/%s%s.expand" % (ctx.label.name, name, len(_dirs)),
- ),
+ kt_toolchain,
+ file_factory.declare_directory("%s.expand" % len(_dirs)),
srcjar,
- extra_args = ["*.java", "*.kt"],
),
)
_srcjars.extend(srcjars)
@@ -789,6 +804,7 @@
output = None,
output_srcjar = None, # Will derive default filename if not set.
deps = [],
+ codegen_output_java_infos = [], # JavaInfo sequence from kt_codegen_plugin.
exports = [], # passthrough for JavaInfo constructor
runtime_deps = [], # passthrough for JavaInfo constructor
native_libraries = [], # passthrough of CcInfo for JavaInfo constructor
@@ -815,12 +831,13 @@
if not kt_toolchain:
fail("Missing or invalid kt_toolchain")
- merged_deps = java_common.merge(deps)
+ file_factory = FileFactory(ctx, output)
+ deps = list(deps) # Defensive copy
# Split sources, as java requires a separate compile step.
kt_srcs = [s for s in srcs if _is_kt_src(s)]
java_srcs = [s for s in srcs if s.path.endswith(_EXT.JAVA)]
- java_syncer = _DirSrcjarSyncer(ctx, kt_toolchain, "java")
+ java_syncer = _DirSrcjarSyncer(ctx, kt_toolchain, file_factory)
java_syncer.add_dirs([s for s in srcs if _is_dir(s, "java")])
java_syncer.add_srcjars([s for s in srcs if s.path.endswith(_EXT.SRCJAR)])
@@ -829,22 +846,20 @@
if sets.length(unexpected_srcs) != 0:
fail("Unexpected srcs: %s" % sets.to_list(unexpected_srcs))
+ # TODO: Remove this special case
+ if kt_srcs and ("flogger" in [p.plugin_id for p in plugins.kt_compiler_plugin_infos]):
+ deps.append(kt_toolchain.flogger_runtime)
+
+ if srcs or common_srcs or rule_family != _RULE_FAMILY.ANDROID_LIBRARY:
+ deps.extend(kt_toolchain.kotlin_libs)
+
# 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).
@@ -861,16 +876,17 @@
out_jars = []
out_srcjars = []
out_compilejars = []
- kapt_outputs = struct(jar = None, manifest = None, srcjar = None)
# 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,
+ file_factory = file_factory,
kt_srcs = kt_srcs,
common_srcs = common_srcs,
java_srcs = java_srcs,
@@ -890,19 +906,15 @@
out_jars.append(kapt_outputs.jar)
java_syncer.add_srcjars([kapt_outputs.srcjar])
- merged_deps = java_common.merge([merged_deps, JavaInfo(
- output_jar = kapt_outputs.jar,
- compile_jar = kapt_outputs.jar,
- )])
-
kotlinc_result = None
if kt_srcs or common_srcs:
kotlinc_result = _run_kotlinc(
ctx,
kt_srcs = kt_srcs,
common_srcs = common_srcs,
+ coverage_srcs = coverage_srcs,
java_srcs_and_dirs = java_srcs + java_syncer.dirs,
- output = ctx.actions.declare_file(ctx.label.name + "-kt.jar"),
+ file_factory = file_factory.derive("-kt"),
kotlincopts = kotlincopts,
compile_jdeps = compile_jdeps,
toolchain = kt_toolchain,
@@ -917,21 +929,7 @@
# (see b/110763361 for the comparable Gradle issue)
out_compilejars.append(kotlinc_result.compile_jar)
out_srcjars.append(kotlinc_result.source_jar)
-
- # Apply coverage instrumentation if requested, and 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():
- out_jars.append(_offline_instrument_jar(
- ctx,
- kt_toolchain,
- kotlinc_result.output_jar,
- kt_srcs + common_srcs + coverage_srcs,
- ))
- merged_deps = java_common.merge([merged_deps, kt_toolchain.coverage_runtime])
- else:
- out_jars.append(kotlinc_result.output_jar)
+ out_jars.append(kotlinc_result.output_jar)
classpath_resources_dirs, classpath_resources_non_dirs = _partition(
classpath_resources,
@@ -941,8 +939,8 @@
out_jars.append(
_create_jar_from_tree_artifacts(
ctx,
- kt_toolchain.jar_tool,
- ctx.actions.declare_file(ctx.label.name + "-dir-res.jar"),
+ kt_toolchain,
+ file_factory.declare_file("-dir-res.jar"),
classpath_resources_dirs,
),
)
@@ -951,15 +949,31 @@
java_native_headers_jar = None
java_gensrcjar = None
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_out = ctx.actions.declare_file(ctx.label.name + "-java.jar")
+ 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,
source_files = java_srcs,
source_jars = java_syncer.srcjars,
resources = classpath_resources_non_dirs,
+ # For targets that are not android_library with java-only srcs, exports will be passed
+ # to the final constructed JavaInfo.
+ exports = exports if is_android_library_without_kt_srcs else [],
output = javac_out,
- deps = ([JavaInfo(**structs.to_dict(kotlinc_result))] if kotlinc_result else []) + [merged_deps],
+ exported_plugins = exported_plugins,
+ 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.
@@ -973,6 +987,15 @@
annotation_processor_additional_outputs = annotation_processor_additional_outputs,
annotation_processor_additional_inputs = annotation_processor_additional_inputs,
)
+
+ # Directly return the JavaInfo from java.compile() for java-only andorid_library targets
+ # to avoid creating a new JavaInfo. See b/239847857 for additional context.
+ if is_android_library_without_kt_srcs:
+ 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
@@ -995,8 +1018,8 @@
blocking_action_outs = []
if output_srcjar == None:
- output_srcjar = ctx.actions.declare_file("lib%s-src.jar" % ctx.label.name)
- compile_jar = ctx.actions.declare_file(ctx.label.name + "-compile.jar")
+ output_srcjar = file_factory.declare_file("-src.jar")
+ compile_jar = file_factory.declare_file("-compile.jar")
single_jar = java_toolchain.single_jar
_singlejar(ctx, out_srcjars, output_srcjar, single_jar, mnemonic = "KtMergeSrcjar", content = "srcjar", preserve_compression = True)
@@ -1043,39 +1066,41 @@
def _kt_jvm_import(
ctx,
+ kt_toolchain,
jars = [],
srcjar = None,
deps = [],
runtime_deps = [],
neverlink = False,
- java_toolchain = None,
+ java_toolchain = None,
deps_checker = None):
if not java_toolchain:
fail("Missing or invalid java_toolchain")
- merged_deps = java_common.merge(deps)
+ if not jars:
+ fail("Must import at least one JAR")
+
+ file_factory = FileFactory(ctx, jars[0])
+ deps = java_common.merge(deps + kt_toolchain.kotlin_libs)
# Check that any needed deps are declared unless neverlink, in which case Jars won't be used
# at runtime so we skip the check, though we'll populate jdeps either way.
- jdeps_output = ctx.actions.declare_file(ctx.label.name + ".jdeps")
- _check_deps(
+ jdeps_output = file_factory.declare_file(".jdeps")
+ _run_import_deps_checker(
ctx,
jars_to_check = jars,
- merged_deps = merged_deps,
+ merged_deps = deps,
enforce_strict_deps = not neverlink,
jdeps_output = jdeps_output,
deps_checker = deps_checker,
java_toolchain = java_toolchain,
)
- if not jars:
- fail("Must provide a Jar to use kt_jvm_import")
-
java_info = java_common.merge([
JavaInfo(
output_jar = jar,
compile_jar = jar,
source_jar = srcjar,
- deps = deps,
+ deps = [deps],
runtime_deps = runtime_deps,
neverlink = neverlink,
# TODO: Set compile-time jdeps to help reduce Javac classpaths downstream
@@ -1140,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:
@@ -1161,6 +1197,7 @@
collect_proguard_specs = _collect_proguard_specs,
collect_providers = _collect_providers,
create_jar_from_tree_artifacts = _create_jar_from_tree_artifacts,
+ common_kapt_and_kotlinc_args = _common_kapt_and_kotlinc_args,
is_kt_src = _is_kt_src,
kt_jvm_import = _kt_jvm_import,
kt_jvm_library = _kt_jvm_library,
diff --git a/kotlin/dex_aspects.bzl b/kotlin/dex_aspects.bzl
new file mode 100644
index 0000000..3d2730b
--- /dev/null
+++ b/kotlin/dex_aspects.bzl
@@ -0,0 +1,36 @@
+# 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_dex_aspects"""
+
+# (b/259111128) Magic provider to get DexArchiveAspect to traverse into this rule
+_TraverseMeInfo = platform_common.ToolchainInfo
+
+_EXTRA_DEPS_ATTRS = dict(
+ _build_stamp_deps = attr.label_list(
+ doc = """
+ (b/259111128) Magic attr to get DexArchiveAspect to traverse into this rule
+ """,
+ ),
+)
+
+def _set_extra_deps_attrs(deps):
+ return {"$build_stamp_deps": deps}
+
+kt_dex_aspects = struct(
+ TraverseMeInfo = _TraverseMeInfo,
+ TRAVERSE_ME_INFO = _TraverseMeInfo(),
+ extra_deps_attrs = _EXTRA_DEPS_ATTRS,
+ set_extra_deps_attrs = _set_extra_deps_attrs,
+)
diff --git a/kotlin/file_factory.bzl b/kotlin/file_factory.bzl
new file mode 100644
index 0000000..25c2837
--- /dev/null
+++ b/kotlin/file_factory.bzl
@@ -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.
+
+"""FileFactory"""
+
+def FileFactory(ctx, base, suffix = None):
+ """Creates files with names derived from some base file
+
+ Including the name of a rule is not always enough to guarantee unique filenames. For example,
+ helper functions that declare their own output files may be called multiple times in the same
+ rule impl.
+
+ Args:
+ ctx: ctx
+ base: [File] The file to derive other filenames from
+ suffix: [Optional[string]] An additional suffix to differentiate declared files
+
+ Returns:
+ FileFactory
+ """
+
+ base_name = base.basename.rsplit(".", 1)[0] + (suffix or "")
+
+ def declare_directory(suffix):
+ return ctx.actions.declare_directory(base_name + suffix, sibling = base)
+
+ def declare_file(suffix):
+ return ctx.actions.declare_file(base_name + suffix, sibling = base)
+
+ def derive(suffix):
+ return FileFactory(ctx, base, suffix)
+
+ return struct(
+ declare_directory = declare_directory,
+ declare_file = declare_file,
+ derive = derive,
+ )
diff --git a/kotlin/friend_jars.bzl b/kotlin/friend_jars.bzl
index 4efb435..1be3f63 100644
--- a/kotlin/friend_jars.bzl
+++ b/kotlin/friend_jars.bzl
@@ -14,29 +14,37 @@
"""TODO: Write module docstring."""
-def _is_eligible_friend(target, friend):
+def is_eligible_friend(target, friend):
"""
- Determines if `target` is allowed to call `friend` a friend (and use its `internal` members).
+ Determines if `target` is allowed to use `internal` members of `friend`
- To be eligible, `target` must be one of:
- - in the parallel `java/` package from a `javatests/` package
- - in the parallel `main/java` package from a `test/java` package
- - another target in the same `BUILD` file
+ To be eligible, one of:
+ 1. `target` and `friend` in same pkg
+ 2. `target` in `testing/` subpkg of `friend` pkg
+ 3. `target` in `javatests/` pkg, `friend` in parallel `java/` pkg
+ 4. `target` in `test/java/` pkg, `friend` in parallel `main/java/` pkg
Args:
target: (target) The current target
friend: (Target) A potential friend of `target`
+
+ Returns:
+ True if `friend` is an eligible friend of `target`.
"""
target_pkg = target.label.package + "/"
friend_pkg = friend.label.package + "/"
if target_pkg == friend_pkg:
- # Allow friends on targets in the same package
+ # Case 1
+ return True
+
+ if target_pkg.removesuffix("testing/") == friend_pkg:
+ # Case 2
return True
if "javatests/" in target_pkg and "java/" in friend_pkg:
- # Allow friends from javatests/ on the parallel java/ package
+ # Case 3
target_java_pkg = target_pkg.rsplit("javatests/", 1)[1]
friend_java_pkg = friend_pkg.rsplit("java/", 1)[1]
if target_java_pkg == friend_java_pkg:
@@ -44,7 +52,7 @@
if ("test/java/" in target_pkg and "main/java/" in friend_pkg and
True):
- # Allow friends from test/java on the parallel main/java package
+ # Case 4
target_split = target_pkg.rsplit("test/java/", 1)
friend_split = friend_pkg.rsplit("main/java/", 1)
if target_split == friend_split:
@@ -60,7 +68,18 @@
kt_friend_jars_visitor = struct(
name = "friend_jars",
visit_target = _get_output_jars,
- filter_edge = _is_eligible_friend,
+ filter_edge = is_eligible_friend,
+ finish_expansion = None,
+ process_unvisited_target = None,
+)
+
+def _get_output_labels(target, _):
+ return [target.label]
+
+kt_friend_labels_visitor = struct(
+ name = "friend_labels",
+ visit_target = _get_output_labels,
+ filter_edge = is_eligible_friend,
finish_expansion = None,
process_unvisited_target = None,
)
diff --git a/kotlin/java_plugin.internal.bzl b/kotlin/java_plugin.internal.bzl
index 08f5463..69e7bb5 100644
--- a/kotlin/java_plugin.internal.bzl
+++ b/kotlin/java_plugin.internal.bzl
@@ -22,7 +22,7 @@
def _get_java_plugins(_target, ctx_rule):
exported_plugins = getattr(ctx_rule.attr, "exported_plugins", [])
return [
- t[JavaPluginInfo]
+ t[JavaPluginInfo].plugins
for t in exported_plugins
if JavaPluginInfo in t
]
diff --git a/kotlin/jvm_compile.bzl b/kotlin/jvm_compile.bzl
index 694a8a4..4139150 100644
--- a/kotlin/jvm_compile.bzl
+++ b/kotlin/jvm_compile.bzl
@@ -15,8 +15,8 @@
"""Compile method that can compile kotlin or java sources"""
load(":common.bzl", "common")
-load(":traverse_exports.bzl", "kt_traverse_exports")
load(":compiler_plugin.bzl", "KtCompilerPluginInfo")
+load(":traverse_exports.bzl", "kt_traverse_exports")
load("@bazel_skylib//lib:sets.bzl", "sets")
_RULE_FAMILY = common.RULE_FAMILY
@@ -46,7 +46,6 @@
disable_lint_checks = [],
r_java = None,
output_srcjar = None,
- flogger_runtime = None,
rule_family = _RULE_FAMILY.UNKNOWN,
annotation_processor_additional_outputs = [],
annotation_processor_additional_inputs = [],
@@ -87,7 +86,6 @@
NOTE: This field accepts a JavaInfo, but should only be used for the
Android R.java within an android_library rule.
output_srcjar: Target output file for generated source jar. Default filename used if None.
- flogger_runtime: JavaInfo, Flogger runtime. Optional
rule_family: The family of the rule calling this function. Element of common.RULE_FAMILY.
May be used to enable/disable some features.
annotation_processor_additional_outputs: sequence of Files. A list of
@@ -110,6 +108,9 @@
# dependent libraries.
fail("Expected one of (srcs, common_srcs, exports) is not empty for kotlin/jvm_compile on target: {}".format(ctx.label))
+ if classpath_resources and rule_family != _RULE_FAMILY.JVM_LIBRARY:
+ fail("resources attribute only allowed for jvm libraries")
+
if type(java_toolchain) != "JavaToolchainInfo":
# Allow passing either a target or a provider until all callers are updated
java_toolchain = java_toolchain[java_common.JavaToolchainInfo]
@@ -117,8 +118,21 @@
srcs = list(srcs)
classpath_resources = list(classpath_resources)
java_infos = []
+ codegen_output_java_infos = []
+
+ # The r_java field only support Android resources Jar files. For now, verify
+ # that the name of the jar matches "_resources.jar". This check does not to
+ # prevent malicious use, the intent is to prevent accidental usage.
+ r_java_infos = []
+ if r_java:
+ for jar in r_java.outputs.jars:
+ if not jar.class_jar.path.endswith("_resources.jar"):
+ fail("Error, illegal dependency provided for r_java. This " +
+ "only supports Android resource Jar files, " +
+ "'*_resources.jar'.")
+ r_java_infos.append(r_java)
+
pre_processed_java_plugin_processors = sets.make([])
- use_flogger = False
# Skip deps validation check for any android_library target with no kotlin sources: b/239721906
has_kt_srcs = any([common.is_kt_src(src) for src in srcs])
@@ -126,52 +140,29 @@
kt_traverse_exports.expand_forbidden_deps(deps + runtime_deps + exports)
for dep in deps:
- # Collect JavaInfo providers and info about plugins (JavaPluginData).
- if JavaInfo in dep:
+ if False:
+ pass
+ elif JavaInfo in dep:
java_infos.append(dep[JavaInfo])
-
else:
fail("Unexpected dependency (must provide JavaInfo): %s" % dep.label)
- if rule_family != _RULE_FAMILY.ANDROID_LIBRARY or srcs or common_srcs:
- java_infos.extend(kt_toolchain.kotlin_libs)
-
- # TODO: Inject the runtime library from the flogger API target
- if use_flogger:
- if not flogger_runtime:
- fail("Dependency on flogger exists, but flogger_runtime not passed")
- java_infos.append(flogger_runtime)
-
if kotlincopts != None and "-Werror" in kotlincopts:
fail("Flag -Werror is not permitted")
- if classpath_resources and rule_family != _RULE_FAMILY.JVM_LIBRARY:
- fail("resources attribute only allowed for jvm libraries")
-
- # The r_java field only support Android resources Jar files. For now, verify
- # that the name of the jar matches "_resources.jar". This check does not to
- # prevent malicious use, the intent is to prevent accidental usage.
- r_java_info = []
- if r_java:
- for jar in r_java.outputs.jars:
- if not jar.class_jar.path.endswith("_resources.jar"):
- fail("Error, illegal dependency provided for r_java. This " +
- "only supports Android resource Jar files, " +
- "'*_resources.jar'.")
- r_java_info.append(r_java)
-
return common.kt_jvm_library(
ctx,
- android_lint_plugins = android_lint_plugins, # List of JavaInfo
+ android_lint_plugins = [p[JavaInfo] for p in android_lint_plugins],
android_lint_rules_jars = android_lint_rules_jars,
classpath_resources = classpath_resources,
common_srcs = common_srcs,
coverage_srcs = coverage_srcs,
- deps = r_java_info + java_infos,
+ deps = r_java_infos + java_infos,
+ codegen_output_java_infos = codegen_output_java_infos,
disable_lint_checks = disable_lint_checks,
exported_plugins = [e[JavaPluginInfo] for e in exported_plugins if (JavaPluginInfo in e)],
# Not all exported targets contain a JavaInfo (e.g. some only have CcInfo)
- exports = r_java_info + [e[JavaInfo] for e in exports if JavaInfo in e],
+ exports = r_java_infos + [e[JavaInfo] for e in exports if JavaInfo in e],
friend_jars = kt_traverse_exports.expand_friend_jars(deps, root = ctx),
java_toolchain = java_toolchain,
javacopts = javacopts,
@@ -202,6 +193,3 @@
annotation_processor_additional_outputs = annotation_processor_additional_outputs,
annotation_processor_additional_inputs = annotation_processor_additional_inputs,
)
-
-# TODO Delete this
-compile = kt_jvm_compile
diff --git a/kotlin/jvm_import.bzl b/kotlin/jvm_import.bzl
index ed740ca..c42bb96 100644
--- a/kotlin/jvm_import.bzl
+++ b/kotlin/jvm_import.bzl
@@ -24,19 +24,8 @@
def _kt_jvm_import_impl(ctx):
kt_jvm_toolchain = kt_jvm_toolchains.get(ctx)
- if not ctx.files.jars:
- fail("List of jars cannot be empty")
-
- deps_java_infos = []
- for dep in ctx.attr.deps:
- deps_java_infos.append(dep[JavaInfo])
-
- # Put Kotlin's standard libs last to match what kotlinc would do without -no-stdlib
- deps_java_infos.extend(kt_jvm_toolchain.kotlin_libs)
-
runtime_deps_java_infos = []
for runtime_dep in ctx.attr.runtime_deps:
- # Collect JavaInfo providers
if JavaInfo in runtime_dep:
runtime_deps_java_infos.append(runtime_dep[JavaInfo])
elif CcInfo not in runtime_dep:
@@ -44,15 +33,15 @@
result = common.kt_jvm_import(
ctx,
+ kt_toolchain = kt_jvm_toolchain,
jars = ctx.files.jars,
srcjar = ctx.file.srcjar,
- deps = deps_java_infos,
+ deps = common.collect_providers(JavaInfo, ctx.attr.deps),
runtime_deps = runtime_deps_java_infos,
neverlink = ctx.attr.neverlink,
java_toolchain = java_toolchains.get(ctx),
deps_checker = ctx.executable._deps_checker,
)
- result_java_info = result.java_info
# Collect runfiles from deps unless neverlink
runfiles = None
@@ -68,7 +57,7 @@
)
return [
- result_java_info,
+ result.java_info,
ProguardSpecProvider(common.collect_proguard_specs(
ctx,
ctx.files.proguard_specs,
diff --git a/kotlin/jvm_library.bzl b/kotlin/jvm_library.bzl
index f2ffe09..916e358 100644
--- a/kotlin/jvm_library.bzl
+++ b/kotlin/jvm_library.bzl
@@ -16,6 +16,7 @@
load(":jvm_library.internal.bzl", "kt_jvm_library_helper")
load("//bazel:stubs.bzl", "register_extension_info")
+load("@bazel_skylib//lib:dicts.bzl", "dicts")
def kt_jvm_library(
name,
@@ -30,16 +31,11 @@
exported_plugins = None,
resources = None,
tags = None,
- testonly = None, # None to preserve Blaze's defaults, b/112708042
javacopts = None,
custom_kotlincopts = None,
disable_lint_checks = None,
- compatible_with = None,
- restricted_to = None,
transitive_configs = None,
- visibility = None,
- deprecation = None,
- features = []):
+ **kwargs):
"""This rule compiles Kotlin (and Java) sources into a Jar file.
Most Java-like libraries
@@ -67,15 +63,11 @@
javacopts: Additional flags to pass to javac if used.
custom_kotlincopts: Additional flags to pass to Kotlin compiler.
disable_lint_checks: A list of AndroidLint checks to be skipped.
- compatible_with: Standard attribute, see
- https://bazel.build/reference/be/common-definitions#common.compatible_with.
- restricted_to: Standard attribute, see
- https://bazel.build/reference/be/common-definitions#common.restricted_to.
transitive_configs: Blaze feature flags (if any) on which this target depends.
- visibility: A list of targets allowed to depend on this rule.
deprecation: Standard attribute, see
https://bazel.build/reference/be/common-definitions#common.deprecation.
features: Features enabled.
+ **kwargs: Other keyword arguments.
"""
srcs = srcs or []
common_srcs = common_srcs or []
@@ -111,13 +103,10 @@
data = data,
disable_lint_checks = disable_lint_checks,
tags = tags,
- testonly = testonly,
- compatible_with = compatible_with,
- restricted_to = restricted_to,
transitive_configs = transitive_configs,
- visibility = visibility,
- deprecation = deprecation,
- features = features,
+ **dicts.add(
+ kwargs,
+ )
)
register_extension_info(
diff --git a/kotlin/jvm_library.internal.bzl b/kotlin/jvm_library.internal.bzl
index 7334f95..85b9e52 100644
--- a/kotlin/jvm_library.internal.bzl
+++ b/kotlin/jvm_library.internal.bzl
@@ -45,9 +45,7 @@
kt_jvm_toolchain = kt_jvm_toolchains.get(ctx)
for target in ctx.attr.runtime_deps:
- if JavaInfo in target:
- pass
- elif CcInfo not in target:
+ if (JavaInfo not in target) and (CcInfo not in target):
fail("Unexpected runtime dependency (must provide JavaInfo or CcInfo): " + str(target.label))
if not ctx.files.srcs and not ctx.files.common_srcs and not ctx.attr.exports and not ctx.attr.exported_plugins:
@@ -66,9 +64,9 @@
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 = [p[JavaInfo] for p in ctx.attr._android_lint_plugins],
+ android_lint_plugins = ctx.attr._android_lint_plugins,
manifest = None,
merged_manifest = None,
resource_files = [],
@@ -189,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/kotlin/jvm_test.bzl b/kotlin/jvm_test.bzl
index b7270e2..1c19902 100644
--- a/kotlin/jvm_test.bzl
+++ b/kotlin/jvm_test.bzl
@@ -36,7 +36,7 @@
"""Wrapper around kt_jvm_library and java_test to conveniently declare tests written in Kotlin.
Use of this rule is discouraged for simple unit tests, which should instead use
- go/junit-test-suites or other, more efficient ways of compiling and running unit tests.
+ go/junit_test_suites or other, more efficient ways of compiling and running unit tests.
Args:
name: Name of the target.
@@ -49,6 +49,7 @@
runtime_deps: A list of runtime dependencies.
srcs: A list of sources to compile.
tags: A list of string tags passed to generated targets.
+ resources: A list of data files to include in the jar file.
**kwargs: Additional parameters to pass on to generated java_test, see go/be-java#java_test.
"""
if srcs:
diff --git a/kotlin/traverse_exports.bzl b/kotlin/traverse_exports.bzl
index e579080..a8ce86f 100644
--- a/kotlin/traverse_exports.bzl
+++ b/kotlin/traverse_exports.bzl
@@ -17,7 +17,7 @@
load(":compiler_plugin.bzl", "kt_compiler_plugin_visitor")
load(":direct_jdeps.bzl", "kt_direct_jdeps_visitor")
load(":forbidden_deps.bzl", "kt_forbidden_deps_visitor")
-load(":friend_jars.bzl", "kt_friend_jars_visitor")
+load(":friend_jars.bzl", "kt_friend_jars_visitor", "kt_friend_labels_visitor")
load(":java_plugin.internal.bzl", "java_plugin_visitor")
# java_xxx_proto_library don't populate java_outputs but we can get them through
@@ -29,7 +29,6 @@
]
_NO_SRCS_DEPS_AS_EXPORTS_RULES = [
- "android_library",
"proto_library",
]
@@ -45,6 +44,7 @@
kt_direct_jdeps_visitor,
kt_compiler_plugin_visitor,
kt_friend_jars_visitor,
+ kt_friend_labels_visitor,
java_plugin_visitor,
]
@@ -65,7 +65,7 @@
if not (JavaInfo in target):
# Ignore non-JVM targets. This also chops-up the
# traversal domain at these targets.
- # TODO: Supoprt non-JVM targets for KMP
+ # TODO: Support non-JVM targets for KMP
return _EMPTY_KT_TRAVERSE_EXPORTS_INFO
exports = []
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 3c4a7db..538bdce 100644
--- a/tests/analysis/jvm_library/friends/BUILD
+++ b/tests/analysis/jvm_library/friends/BUILD
@@ -13,6 +13,7 @@
# limitations under the License.
load("//kotlin:rules.bzl", "kt_jvm_library")
+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")
@@ -24,35 +25,72 @@
licenses(["notice"])
jvm_library_test(
- name = "no_kt_exported_friend_trans_package_test",
+ name = "no_kt_exported_friend_cross_package_test",
expected_friend_jar_names = [],
- target_under_test = ":no_kt_exported_friend_trans_package",
-)
-
-kt_jvm_library(
- name = "no_kt_exported_friend_trans_package",
- srcs = ["Input.kt"],
- tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
- deps = [
- # Exports :friend from this package
- "//tests/analysis/jvm_library/friends/sub:kt_exports_friend",
- ],
+ target_under_test = rules_for_test.kt_jvm_library(
+ name = "no_kt_exported_friend_cross_package",
+ srcs = ["Input.kt"],
+ deps = [
+ # Exports :friend from this package
+ "//tests/analysis/jvm_library/friends/sub:kt_exports_friend",
+ ],
+ ),
)
jvm_library_test(
name = "has_java_exported_friend_in_package_test",
expected_friend_jar_names = [
"libjava_exports_friend-hjar.jar",
- "friend-compile.jar",
+ "libfriend-compile.jar",
],
- target_under_test = ":has_java_exported_friend_in_package",
+ target_under_test = rules_for_test.kt_jvm_library(
+ name = "has_java_exported_friend_in_package",
+ srcs = ["Input.kt"],
+ deps = [":java_exports_friend"],
+ ),
)
-kt_jvm_library(
- name = "has_java_exported_friend_in_package",
- srcs = ["Input.kt"],
- tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
- deps = [":java_exports_friend"],
+jvm_library_test(
+ name = "has_kt_exported_friend_in_package_test",
+ expected_friend_jar_names = [
+ "libkt_exports_friend-compile.jar",
+ "libfriend-compile.jar",
+ ],
+ target_under_test = rules_for_test.kt_jvm_library(
+ name = "has_kt_exported_friend_in_package",
+ srcs = ["Input.kt"],
+ deps = [":kt_exports_friend"],
+ ),
+)
+
+jvm_library_test(
+ name = "no_direct_friend_testing_package_test",
+ expected_friend_jar_names = [],
+ 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"],
+ ),
+)
+
+jvm_library_test(
+ name = "no_direct_friend_subpackage_test",
+ expected_friend_jar_names = [],
+ 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"],
+ ),
+)
+
+jvm_library_test(
+ name = "has_direct_friend_in_package_test",
+ expected_friend_jar_names = ["libfriend-compile.jar"],
+ target_under_test = rules_for_test.kt_jvm_library(
+ name = "has_direct_friend_in_package",
+ srcs = ["Input.kt"],
+ deps = [":friend"],
+ ),
)
java_library(
@@ -62,22 +100,6 @@
exports = [":friend"],
)
-jvm_library_test(
- name = "has_kt_exported_friend_in_package_test",
- expected_friend_jar_names = [
- "kt_exports_friend-compile.jar",
- "friend-compile.jar",
- ],
- target_under_test = ":has_kt_exported_friend_in_package",
-)
-
-kt_jvm_library(
- name = "has_kt_exported_friend_in_package",
- srcs = ["Input.kt"],
- tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
- deps = [":kt_exports_friend"],
-)
-
kt_jvm_library(
name = "kt_exports_friend",
srcs = ["Input.kt"],
@@ -85,19 +107,6 @@
exports = [":friend"],
)
-jvm_library_test(
- name = "has_direct_friend_in_package_test",
- expected_friend_jar_names = ["friend-compile.jar"],
- target_under_test = ":has_direct_friend_in_package",
-)
-
-kt_jvm_library(
- name = "has_direct_friend_in_package",
- srcs = ["Input.kt"],
- tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
- deps = [":friend"],
-)
-
kt_jvm_library(
name = "friend",
srcs = ["Input.kt"],
diff --git a/tests/analysis/jvm_library/friends/sub/BUILD b/tests/analysis/jvm_library/friends/sub/BUILD
index 7c26e59..e7c619f 100644
--- a/tests/analysis/jvm_library/friends/sub/BUILD
+++ b/tests/analysis/jvm_library/friends/sub/BUILD
@@ -13,6 +13,7 @@
# limitations under the License.
load("//kotlin:rules.bzl", "kt_jvm_library")
+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")
@@ -26,17 +27,24 @@
jvm_library_test(
name = "no_kt_exported_friend_cross_package_test",
expected_friend_jar_names = [
- "kt_exports_friend-compile.jar",
- # Absent # "friend-compile.jar"
+ "libkt_exports_friend-compile.jar",
+ # Absent # "libfriend-compile.jar"
],
- target_under_test = ":no_kt_exported_friend_cross_package",
+ target_under_test = rules_for_test.kt_jvm_library(
+ name = "no_kt_exported_friend_cross_package",
+ srcs = ["Input.kt"],
+ deps = [":kt_exports_friend"],
+ ),
)
-kt_jvm_library(
- name = "no_kt_exported_friend_cross_package",
- srcs = ["Input.kt"],
- tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
- deps = [":kt_exports_friend"],
+jvm_library_test(
+ name = "no_direct_friend_cross_package_test",
+ expected_friend_jar_names = [],
+ 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"],
+ ),
)
kt_jvm_library(
@@ -46,15 +54,8 @@
exports = ["//tests/analysis/jvm_library/friends:friend"],
)
-jvm_library_test(
- name = "no_direct_friend_cross_package_test",
- expected_friend_jar_names = [],
- target_under_test = ":no_direct_friend_cross_package",
-)
-
kt_jvm_library(
- name = "no_direct_friend_cross_package",
+ name = "subfriend",
srcs = ["Input.kt"],
tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
- 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
new file mode 100644
index 0000000..827aa30
--- /dev/null
+++ b/tests/analysis/jvm_library/friends/testing/BUILD
@@ -0,0 +1,93 @@
+# 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("//kotlin:rules.bzl", "kt_jvm_library")
+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(
+ default_testonly = True,
+ default_visibility = ["//tests/analysis/jvm_library/friends:__subpackages__"],
+)
+
+licenses(["notice"])
+
+jvm_library_test(
+ name = "has_kt_exported_friend_impl_package_test",
+ expected_friend_jar_names = [
+ "libkt_exports_friend-compile.jar",
+ "libfriend-compile.jar",
+ ],
+ target_under_test = rules_for_test.kt_jvm_library(
+ name = "has_kt_exported_friend_impl_package",
+ srcs = ["Input.kt"],
+ deps = [":kt_exports_friend"],
+ ),
+)
+
+jvm_library_test(
+ name = "has_direct_friend_impl_package_test",
+ expected_friend_jar_names = [
+ "libfriend-compile.jar",
+ ],
+ 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"],
+ ),
+)
+
+jvm_library_test(
+ name = "no_kt_exported_friend_sibling_package_test",
+ expected_friend_jar_names = [
+ "libkt_exports_subfriend-compile.jar",
+ # Absent # "subfriend-compile.jar"
+ ],
+ target_under_test = rules_for_test.kt_jvm_library(
+ name = "no_kt_exported_friend_sibling_package",
+ srcs = ["Input.kt"],
+ deps = [":kt_exports_subfriend"],
+ ),
+)
+
+jvm_library_test(
+ name = "no_direct_friend_sibling_package_test",
+ expected_friend_jar_names = [],
+ 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"],
+ ),
+)
+
+kt_jvm_library(
+ name = "kt_exports_subfriend",
+ srcs = ["Input.kt"],
+ tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
+ exports = ["//tests/analysis/jvm_library/friends/sub:subfriend"],
+)
+
+kt_jvm_library(
+ name = "kt_exports_friend",
+ srcs = ["Input.kt"],
+ tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
+ exports = ["//tests/analysis/jvm_library/friends:friend"],
+)
+
+kt_jvm_library(
+ name = "testingfriend",
+ srcs = ["Input.kt"],
+ tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
+)
diff --git a/tests/analysis/jvm_library/friends/testing/Input.kt b/tests/analysis/jvm_library/friends/testing/Input.kt
new file mode 100644
index 0000000..2c65124
--- /dev/null
+++ b/tests/analysis/jvm_library/friends/testing/Input.kt
@@ -0,0 +1,17 @@
+/*
+ * * 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.
+ */
+
+package test.testing
diff --git a/tests/analysis/jvm_library/no_java_srcs/BUILD b/tests/analysis/jvm_library/no_java_srcs/BUILD
new file mode 100644
index 0000000..116dcfd
--- /dev/null
+++ b/tests/analysis/jvm_library/no_java_srcs/BUILD
@@ -0,0 +1,30 @@
+# 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 = "no_java_srcs_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_java_srcs/Input.kt b/tests/analysis/jvm_library/no_java_srcs/Input.kt
new file mode 100644
index 0000000..e675bc1
--- /dev/null
+++ b/tests/analysis/jvm_library/no_java_srcs/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/no_kt_srcs/BUILD b/tests/analysis/jvm_library/no_kt_srcs/BUILD
new file mode 100644
index 0000000..a6e4f18
--- /dev/null
+++ b/tests/analysis/jvm_library/no_kt_srcs/BUILD
@@ -0,0 +1,30 @@
+# 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 = "no_kt_srcs_test",
+ target_under_test = rules_for_test.kt_jvm_library(
+ name = "no_kt_srcs",
+ srcs = [
+ "Input.java",
+ ],
+ ),
+)
diff --git a/tests/analysis/jvm_library/no_kt_srcs/Input.java b/tests/analysis/jvm_library/no_kt_srcs/Input.java
new file mode 100644
index 0000000..e675bc1
--- /dev/null
+++ b/tests/analysis/jvm_library/no_kt_srcs/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/nodeps/BUILD b/tests/analysis/jvm_library/nodeps/BUILD
new file mode 100644
index 0000000..fc3e673
--- /dev/null
+++ b/tests/analysis/jvm_library/nodeps/BUILD
@@ -0,0 +1,31 @@
+# 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 = "nodeps_test",
+ target_under_test = rules_for_test.kt_jvm_library(
+ name = "nodeps",
+ srcs = [
+ "Input.java",
+ "Input.kt",
+ ],
+ ),
+)
diff --git a/tests/analysis/jvm_library/nodeps/Input.java b/tests/analysis/jvm_library/nodeps/Input.java
new file mode 100644
index 0000000..e675bc1
--- /dev/null
+++ b/tests/analysis/jvm_library/nodeps/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/nodeps/Input.kt b/tests/analysis/jvm_library/nodeps/Input.kt
new file mode 100644
index 0000000..e675bc1
--- /dev/null
+++ b/tests/analysis/jvm_library/nodeps/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/only_common_srcs/BUILD b/tests/analysis/jvm_library/only_common_srcs/BUILD
new file mode 100644
index 0000000..49930f2
--- /dev/null
+++ b/tests/analysis/jvm_library/only_common_srcs/BUILD
@@ -0,0 +1,30 @@
+# 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 = "only_common_srcs_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/only_common_srcs/Input.kt b/tests/analysis/jvm_library/only_common_srcs/Input.kt
new file mode 100644
index 0000000..e675bc1
--- /dev/null
+++ b/tests/analysis/jvm_library/only_common_srcs/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/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 a73bbbc..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,6 +114,7 @@
default = _DEFAULT_LIST,
),
expect_processor_classpath = attr.bool(),
+ expect_neverlink = attr.bool(),
),
)
@@ -139,158 +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_no_deps():
- test_name = "kt_jvm_library_no_deps_test"
- create_file(
- name = test_name + "/Salutations.kt",
- content = """
-package test
-
-fun greeting(): String = "Hello World!"
-""",
- )
- kt_jvm_library(
- name = test_name + "_tut",
- srcs = [
- "testinputs/Bar.java",
- test_name + "/Salutations.kt",
- ],
- )
- _test(
- name = test_name,
- target_under_test = test_name + "_tut",
- )
- return test_name
-
-def _test_kt_jvm_library_with_only_common_srcs():
- test_name = "kt_jvm_library_only_common_srcs_test"
- create_file(
- name = test_name + "/Salutations.kt",
- content = """
-package test
-
-fun greeting(): String = "Hello World!"
-""",
- )
- kt_jvm_library(
- name = test_name + "_tut",
- common_srcs = [
- test_name + "/Salutations.kt",
- ],
- )
- _test(
- name = test_name,
- target_under_test = test_name + "_tut",
- )
- return test_name
-
-def _test_kt_jvm_library_no_java_srcs():
- test_name = "kt_jvm_library_no_java_srcs_test"
- create_file(
- name = test_name + "/Salutations.kt",
- content = """
-package test
-
-fun greeting(): String = "Hello World!"
-""",
- )
- kt_jvm_library(
- name = test_name + "_tut",
- srcs = [
- test_name + "/Salutations.kt",
- ],
- )
- _test(
- name = test_name,
- target_under_test = test_name + "_tut",
- )
- return test_name
-
-def _test_kt_jvm_library_no_kt_srcs():
- test_name = "kt_jvm_library_no_kt_srcs_test"
- kt_jvm_library(
- name = test_name + "_tut",
- srcs = [
- "testinputs/Bar.java",
- ],
- )
- _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(
@@ -356,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(
@@ -816,23 +630,16 @@
_test_forbidden_nano_export(),
_test_kt_jvm_library_dep_on_exported_plugin(),
_test_kt_jvm_library_java_dep_on_exported_plugin(),
- _test_kt_jvm_library_no_deps(),
- _test_kt_jvm_library_no_java_srcs(),
- _test_kt_jvm_library_no_kt_srcs(),
_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(),
_test_kt_jvm_library_with_java_export_that_exports_plugin(),
_test_kt_jvm_library_with_no_sources(),
_test_kt_jvm_library_with_non_processor_plugin(),
- _test_kt_jvm_library_with_only_common_srcs(),
_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/functions/BUILD b/tests/jvm/java/functions/BUILD
index aa571fe..67c0e9e 100644
--- a/tests/jvm/java/functions/BUILD
+++ b/tests/jvm/java/functions/BUILD
@@ -17,6 +17,12 @@
licenses(["notice"])
+# During coverage builds, every library gets a dep on JaCoCo (Java Code Coverage).
+# Libjars, from libraries, only include their direct sources. Together, these behaviours
+# trigger an ImportDepsChecker error for :car-jar and :car-inline-jar. To prevent that, we disable
+# coverage builds on all downstream targets.
+_NO_ZAPFHAHN_BECAUSE_LIBJARS_EXCLUDE_JACOCO = ["nozapfhahn"]
+
kt_jvm_library(
name = "car_demo_src_lib",
srcs = ["CarDemo.kt"],
@@ -38,11 +44,13 @@
java_import(
name = "car-jar",
jars = ["//tests/jvm/java/functions/car:car_lib-jar"],
+ tags = _NO_ZAPFHAHN_BECAUSE_LIBJARS_EXCLUDE_JACOCO,
)
kt_jvm_library(
name = "car_demo_jar_lib",
srcs = ["CarDemo.kt"],
+ tags = _NO_ZAPFHAHN_BECAUSE_LIBJARS_EXCLUDE_JACOCO,
deps = [
":car-jar",
],
@@ -53,7 +61,8 @@
java_test(
name = "car_jar_demo",
main_class = "functions.CarDemo",
- tags = ["darwin_x86_64_compatible"],
+ tags = ["darwin_x86_64_compatible"] +
+ _NO_ZAPFHAHN_BECAUSE_LIBJARS_EXCLUDE_JACOCO,
runtime_deps = [
":car_demo_jar_lib",
"@kotlinc//:kotlin_stdlib",
@@ -66,6 +75,7 @@
"//tests/jvm/java/functions/car:car_inline_lib-jar",
"//tests/jvm/java/functions/car:car_extra_lib-jar",
],
+ tags = _NO_ZAPFHAHN_BECAUSE_LIBJARS_EXCLUDE_JACOCO,
deps = [
":car-jar",
],
@@ -74,6 +84,7 @@
kt_jvm_library(
name = "car_demo_inline_lib",
srcs = ["CarInlineDemo.kt"],
+ tags = _NO_ZAPFHAHN_BECAUSE_LIBJARS_EXCLUDE_JACOCO,
deps = [
":car-inline-jar",
":car-jar",
@@ -85,10 +96,8 @@
java_test(
name = "car_inline_demo",
main_class = "functions.CarInlineDemo",
- tags = [
- "darwin_x86_64_compatible",
- "nozapfhahn",
- ],
+ tags = ["darwin_x86_64_compatible"] +
+ _NO_ZAPFHAHN_BECAUSE_LIBJARS_EXCLUDE_JACOCO,
runtime_deps = [
":car_demo_inline_lib",
"@kotlinc//:kotlin_stdlib",
diff --git a/tests/jvm/java/kapt/AP.java b/tests/jvm/java/kapt/AP.java
index 984a444..d8b6d9f 100644
--- a/tests/jvm/java/kapt/AP.java
+++ b/tests/jvm/java/kapt/AP.java
@@ -63,7 +63,7 @@
.createSourceFile("kapt." + simpleName, element)
.openOutputStream()) {
os.write(
- String.format("package kapt; @Count(%d) class %s {}", next, simpleName)
+ String.format("package kapt; @Count(%d) public class %s {}", next, simpleName)
.getBytes(UTF_8));
} catch (IOException e) {
throw new UncheckedIOException(e);
diff --git a/tests/jvm/java/kapt/BUILD b/tests/jvm/java/kapt/BUILD
index 43b893d..ea6ad66 100644
--- a/tests/jvm/java/kapt/BUILD
+++ b/tests/jvm/java/kapt/BUILD
@@ -21,10 +21,15 @@
licenses(["notice"])
+package(default_visibility = [
+ "//tests/android/java/com/google/local_test:__subpackages__",
+])
+
build_test(
name = "kapt_regressions",
tags = ["darwin_x86_64_compatible"],
targets = [
+ ":test_interface_with_default_impls",
":test_javac",
":test_kapt",
":test_javac",
@@ -52,6 +57,14 @@
)
kt_jvm_library(
+ name = "test_interface_with_default_impls",
+ srcs = [
+ "InterfaceWithDefaultImpls.kt",
+ ],
+ plugins = [":AP"], # trigger kapt for regression test (b/121222399)
+)
+
+kt_jvm_library(
name = "test_kapt",
srcs = [
"KTest.kt",
@@ -194,6 +207,11 @@
srcs = ["Count.java"],
)
+java_library(
+ name = "anno-android",
+ srcs = ["Count.java"],
+)
+
kt_jvm_library(
name = "anno_with_plugin",
srcs = ["Count.java"],
diff --git a/tests/jvm/java/kapt/InterfaceWithDefaultImpls.kt b/tests/jvm/java/kapt/InterfaceWithDefaultImpls.kt
index a9aad4f..0bb1f12 100644
--- a/tests/jvm/java/kapt/InterfaceWithDefaultImpls.kt
+++ b/tests/jvm/java/kapt/InterfaceWithDefaultImpls.kt
@@ -15,7 +15,6 @@
*/
// This file contains the example filed upstream for b/121222399.
-// TODO: Turn this into a regression test once the issue is fixed.
package kapt
interface Base<T>
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.
+ */
+
diff --git a/toolchains/kotlin_jvm/kt_jvm_toolchains.bzl b/toolchains/kotlin_jvm/kt_jvm_toolchains.bzl
index 0b9c610..cc73d81 100644
--- a/toolchains/kotlin_jvm/kt_jvm_toolchains.bzl
+++ b/toolchains/kotlin_jvm/kt_jvm_toolchains.bzl
@@ -14,10 +14,12 @@
"""Kotlin toolchain."""
+load("//bazel:stubs.bzl", "select_java_language_version")
+
# Work around to toolchains in Google3.
KtJvmToolchainInfo = provider()
-KT_VERSION = "v1_7_10"
+KT_VERSION = "v1_7_21"
KT_LANG_VERSION = "1.7"
@@ -102,8 +104,10 @@
coverage_runtime = ctx.attr.coverage_runtime[JavaInfo] if JavaInfo in ctx.attr.coverage_runtime else None,
genclass = ctx.file.genclass,
jar_tool = ctx.attr.jar_tool[DefaultInfo].files_to_run,
+ java_language_version = ctx.attr.java_language_version,
java_runtime = ctx.attr.java_runtime,
jvm_abi_gen_plugin = ctx.file.jvm_abi_gen_plugin,
+ jvm_target = ctx.attr.jvm_target,
kotlin_annotation_processing = ctx.file.kotlin_annotation_processing,
kotlin_compiler = ctx.attr.kotlin_compiler[DefaultInfo].files_to_run,
kotlin_language_version = ctx.attr.kotlin_language_version,
@@ -112,17 +116,18 @@
kotlinc_cli_flags = _kotlinc_cli_flags(ctx),
kotlinc_ide_flags = _kotlinc_ide_flags(ctx),
proguard_whitelister = ctx.attr.proguard_whitelister[DefaultInfo].files_to_run,
+ source_jar_zipper = ctx.file.source_jar_zipper,
turbine = ctx.file.turbine,
turbine_direct = ctx.file.turbine_direct if ctx.attr.enable_turbine_direct else None,
turbine_jsa = ctx.file.turbine_jsa,
+ turbine_java_runtime = ctx.attr.turbine_java_runtime,
)
return [
platform_common.ToolchainInfo(**kt_jvm_toolchain),
KtJvmToolchainInfo(**kt_jvm_toolchain),
]
-_kt_jvm_toolchain_internal = rule(
- name = "kt_jvm_toolchain",
+kt_jvm_toolchain = rule(
attrs = dict(
build_marker = attr.label(
default = "//tools:build_marker",
@@ -152,6 +157,9 @@
allow_files = True,
cfg = "exec",
),
+ java_language_version = attr.string(
+ default = "11",
+ ),
java_runtime = attr.label(
default = "@bazel_tools//tools/jdk:current_java_runtime",
cfg = "exec",
@@ -213,6 +221,11 @@
cfg = "target",
doc = "The Kotlin runtime libraries grouped into one attribute.",
),
+ source_jar_zipper = attr.label(
+ default = "//tools/bin:source_jar_zipper_binary",
+ cfg = "exec",
+ allow_single_file = [".jar"],
+ ),
turbine = attr.label(
default = "@bazel_tools//tools/jdk:turbine_direct",
cfg = "exec",
@@ -227,16 +240,23 @@
cfg = "exec",
allow_single_file = True,
),
+ turbine_java_runtime = attr.label(
+ cfg = "exec",
+ ),
),
provides = [platform_common.ToolchainInfo],
implementation = _kt_jvm_toolchain_impl,
)
-def _kt_jvm_toolchain(**kwargs):
- _kt_jvm_toolchain_internal(
- jvm_target = select({
- "//conditions:default": "11",
- }),
+def _declare(**kwargs):
+ kt_jvm_toolchain(
+ # TODO: use select_java_language_level() after support for Java 8 is dropped
+ jvm_target = select_java_language_version(
+ # The JVM bytecode version to output
+ java8 = "1.8",
+ java11 = "11",
+ java_head = "18", # https://kotlinlang.org/docs/compiler-reference.html#jvm-target-version
+ ),
**kwargs
)
@@ -252,6 +272,6 @@
name = _TYPE.name,
get = lambda ctx: ctx.toolchains[_TYPE],
type = str(_TYPE),
- declare = _kt_jvm_toolchain,
+ declare = _declare,
attrs = _ATTRS,
)
diff --git a/tools/BUILD b/tools/BUILD
index 18f1a9a..02f945c 100644
--- a/tools/BUILD
+++ b/tools/BUILD
@@ -13,6 +13,7 @@
# limitations under the License.
# Description: Kotlin building rules tools
+load("//bazel:deploy_jar_freshness_golden_test.bzl", "deploy_jar_freshness_golden_test")
licenses(["notice"])
@@ -25,3 +26,9 @@
cmd = """$(location @bazel_tools//tools/zip:zipper) c $@ "assets/_kotlin=" """,
tools = ["@bazel_tools//tools/zip:zipper"],
)
+
+deploy_jar_freshness_golden_test(
+ name = "source_jar_zipper_freshness_test",
+ current_jar = "//tools/bin:source_jar_zipper_binary",
+ newly_built_jar = "//tools/java/com/google/devtools/kotlin:source_jar_zipper_deploy.jar",
+)
diff --git a/tools/bin/BUILD b/tools/bin/BUILD
new file mode 100644
index 0000000..b5bc641
--- /dev/null
+++ b/tools/bin/BUILD
@@ -0,0 +1,22 @@
+# 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.
+
+licenses(["notice"]) # Apache 2.0
+
+package(default_visibility = ["//:internal"])
+
+alias(
+ name = "source_jar_zipper_binary",
+ actual = "source_jar_zipper_deploy.jar",
+)
diff --git a/tools/bin/source_jar_zipper_deploy.jar b/tools/bin/source_jar_zipper_deploy.jar
new file mode 100755
index 0000000..5f283fe
--- /dev/null
+++ b/tools/bin/source_jar_zipper_deploy.jar
Binary files differ
diff --git a/tools/java/com/google/devtools/kotlin/BUILD b/tools/java/com/google/devtools/kotlin/BUILD
new file mode 100644
index 0000000..544536b
--- /dev/null
+++ b/tools/java/com/google/devtools/kotlin/BUILD
@@ -0,0 +1,33 @@
+# 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.
+
+# Kotlin building rules tools
+
+load("//kotlin:rules.bzl", "kt_jvm_library")
+
+package(default_visibility = ["//:internal"])
+
+licenses(["notice"])
+
+kt_jvm_library(
+ name = "source_jar_zipper_lib",
+ srcs = ["SourceJarZipper.kt"],
+ deps = ["@maven//:info_picocli_picocli"],
+)
+
+java_binary(
+ name = "source_jar_zipper",
+ main_class = "com.google.devtools.kotlin.SourceJarZipperKt",
+ runtime_deps = [":source_jar_zipper_lib"],
+)
diff --git a/tools/java/com/google/devtools/kotlin/SourceJarZipper.kt b/tools/java/com/google/devtools/kotlin/SourceJarZipper.kt
new file mode 100644
index 0000000..ac57efe
--- /dev/null
+++ b/tools/java/com/google/devtools/kotlin/SourceJarZipper.kt
@@ -0,0 +1,274 @@
+/*
+ * * 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.
+ */
+
+package com.google.devtools.kotlin
+
+import java.io.BufferedInputStream
+import java.io.BufferedOutputStream
+import java.nio.file.Files
+import java.nio.file.Path
+import java.nio.file.Paths
+import java.nio.file.StandardCopyOption
+import java.util.zip.ZipEntry
+import java.util.zip.ZipInputStream
+import java.util.zip.ZipOutputStream
+import kotlin.system.exitProcess
+import picocli.CommandLine
+import picocli.CommandLine.Command
+import picocli.CommandLine.Model.CommandSpec
+import picocli.CommandLine.Option
+import picocli.CommandLine.ParameterException
+import picocli.CommandLine.Parameters
+import picocli.CommandLine.Spec
+
+@Command(
+ name = "source-jar-zipper",
+ subcommands = [Unzip::class, Zip::class, ZipResources::class],
+ description = ["A tool to pack and unpack srcjar files, and to zip resource files"],
+)
+class SourceJarZipper : Runnable {
+ @Spec private lateinit var spec: CommandSpec
+ override fun run() {
+ throw ParameterException(spec.commandLine(), "Specify a command: zip, zip_resources or unzip")
+ }
+}
+
+fun main(args: Array<String>) {
+ val exitCode = CommandLine(SourceJarZipper()).execute(*args)
+ exitProcess(exitCode)
+}
+
+/**
+ * Checks for duplicates and add an entry into [errors] if found any, otherwise adds a pair
+ * of [zipPath] and [sourcePath] to the receiver
+ * @receiver a mutable map of path to path, where keys are relative paths of files inside the
+ * resulting .jar, and values are full paths of files
+ * @param[zipPath] relative path inside the jar, built either from package name
+ * (e.g. package com.google.foo -> com/google/foo/FileName.kt) or by resolving the file name
+ * relatively the directory it came from (e.g. foo/bar/1/2.txt came from foo/bar -> 1/2.txt)
+ * @param[sourcePath] full path of file into its file system
+ * @param[errors] list of strings describing catched errors
+ */
+fun MutableMap<Path, Path>.checkForDuplicatesAndSetFilePathToPathInsideJar(
+ zipPath: Path,
+ sourcePath: Path,
+ errors: MutableList<String>,
+) {
+ val duplicatedSourcePath: Path? = this[zipPath]
+ if (duplicatedSourcePath == null) {
+ this[zipPath] = sourcePath
+ } else {
+ errors.add(
+ "${sourcePath} has the same path inside .jar as ${duplicatedSourcePath}! " +
+ "If it is intended behavior rename one or both of them."
+ )
+ }
+}
+
+fun MutableMap<Path, Path>.writeToStream(
+ zipper: ZipOutputStream,
+ prefix: String = "",
+) {
+ for ((zipPath, sourcePath) in this) {
+ BufferedInputStream(Files.newInputStream(sourcePath)).use { inputStream ->
+ val entry = ZipEntry(Paths.get(prefix).resolve(zipPath).toString())
+ entry.time = 0
+ zipper.putNextEntry(entry)
+ inputStream.copyTo(zipper, bufferSize = 1024)
+ }
+ }
+}
+
+@Command(name = "zip", description = ["Zip source files into a source jar file"])
+class Zip : Runnable {
+
+ @Parameters(index = "0", paramLabel = "outputJar", description = ["Output jar"])
+ lateinit var outputJar: Path
+
+ @Option(
+ names = ["-i", "--ignore_not_allowed_files"],
+ description = ["Ignore not .kt, .java or invalid file paths without raising an exception"],
+ )
+ var ignoreNotAllowedFiles = false
+
+ @Option(
+ names = ["--kotlin_srcs"],
+ split = ",",
+ description = ["Kotlin source files"],
+ )
+ val kotlinSrcs = mutableListOf<Path>()
+
+ @Option(
+ names = ["--common_srcs"],
+ split = ",",
+ description = ["Common source files"],
+ )
+ val commonSrcs = mutableListOf<Path>()
+
+ companion object {
+ const val PACKAGE_SPACE = "package "
+ val PACKAGE_NAME_REGEX = "[a-zA-Z][a-zA-Z0-9_]*(\\.[a-zA-Z0-9_]+)*".toRegex()
+ }
+
+ override fun run() {
+ check(kotlinSrcs.isNotEmpty() or commonSrcs.isNotEmpty()) {
+ "Expected at least one source file."
+ }
+
+ // Validating files and getting paths for resulting .jar in one cycle
+ // for each _srcs list
+ val ktZipPathToSourcePath = mutableMapOf<Path, Path>()
+ val commonZipPathToSourcePath = mutableMapOf<Path, Path>()
+ val errors = mutableListOf<String>()
+
+ fun Path.getPackagePath(): Path {
+ this.toFile().bufferedReader().use { stream ->
+ while (true) {
+ val line = stream.readLine() ?: return this.fileName
+
+ if (line.startsWith(PACKAGE_SPACE)) {
+ // Kotlin allows usage of reserved words in package names framing them
+ // with backquote symbol "`"
+ val packageName =
+ line.substring(PACKAGE_SPACE.length).trim().replace(";", "").replace("`", "")
+ if (!PACKAGE_NAME_REGEX.matches(packageName)) {
+ errors.add("${this} contains an invalid package name")
+ return this.fileName
+ }
+ return Paths.get(packageName.replace(".", "/")).resolve(this.fileName)
+ }
+ }
+ }
+ }
+
+ fun Path.validateFile(): Boolean {
+ when {
+ !Files.isRegularFile(this) -> {
+ if (!ignoreNotAllowedFiles) errors.add("${this} is not a file")
+ return false
+ }
+ !this.toString().endsWith(".kt") && !this.toString().endsWith(".java") -> {
+ if (!ignoreNotAllowedFiles) errors.add("${this} is not a Kotlin file")
+ return false
+ }
+ else -> return true
+ }
+ }
+
+ for (sourcePath in kotlinSrcs) {
+ if (sourcePath.validateFile()) {
+ ktZipPathToSourcePath.checkForDuplicatesAndSetFilePathToPathInsideJar(
+ sourcePath.getPackagePath(),
+ sourcePath,
+ errors,
+ )
+ }
+ }
+
+ for (sourcePath in commonSrcs) {
+ if (sourcePath.validateFile()) {
+ commonZipPathToSourcePath.checkForDuplicatesAndSetFilePathToPathInsideJar(
+ sourcePath.getPackagePath(),
+ sourcePath,
+ errors,
+ )
+ }
+ }
+
+ if (ktZipPathToSourcePath.isEmpty() && commonZipPathToSourcePath.isEmpty()) {
+ errors.add("Expected at least one valid source file .kt or .java")
+ }
+ check(errors.isEmpty()) { errors.joinToString("\n") }
+
+ ZipOutputStream(BufferedOutputStream(Files.newOutputStream(outputJar))).use { zipper ->
+ commonZipPathToSourcePath.writeToStream(zipper, "common-srcs")
+ ktZipPathToSourcePath.writeToStream(zipper)
+ }
+ }
+}
+
+@Command(name = "unzip", description = ["Unzip a jar archive into a specified directory"])
+class Unzip : Runnable {
+
+ @Parameters(index = "0", paramLabel = "inputJar", description = ["Jar archive to unzip"])
+ lateinit var inputJar: Path
+
+ @Parameters(index = "1", paramLabel = "outputDir", description = ["Output directory"])
+ lateinit var outputDir: Path
+
+ override fun run() {
+ ZipInputStream(Files.newInputStream(inputJar)).use { unzipper ->
+ while (true) {
+ val zipEntry: ZipEntry? = unzipper.nextEntry
+ if (zipEntry == null) return
+
+ val entryName = zipEntry.name
+ check(!entryName.contains("./")) { "Cannot unpack srcjar with relative path ${entryName}" }
+
+ if (!entryName.endsWith(".kt") && !entryName.endsWith(".java")) continue
+
+ val entryPath = outputDir.resolve(entryName)
+ if (!Files.exists(entryPath.parent)) Files.createDirectories(entryPath.parent)
+ Files.copy(unzipper, entryPath, StandardCopyOption.REPLACE_EXISTING)
+ }
+ }
+ }
+}
+
+@Command(name = "zip_resources", description = ["Zip resources"])
+class ZipResources : Runnable {
+
+ @Parameters(index = "0", paramLabel = "outputJar", description = ["Output jar"])
+ lateinit var outputJar: Path
+
+ @Option(
+ names = ["--input_dirs"],
+ split = ",",
+ description = ["Input files directories"],
+ required = true,
+ )
+ val inputDirs = mutableListOf<Path>()
+
+ override fun run() {
+ val filePathToOutputPath = mutableMapOf<Path, Path>()
+ val errors = mutableListOf<String>()
+
+ // inputDirs has filter checking if the dir exists, because some empty dirs generated by blaze
+ // may not exist from Kotlin compiler's side. It turned out to be safer to apply a filter then
+ // to rely that generated directories are always directories, not just path names
+ for (dirPath in inputDirs.filter { curDirPath -> Files.exists(curDirPath) }) {
+ if (!Files.isDirectory(dirPath)) {
+ errors.add("${dirPath} is not a directory")
+ } else {
+ Files.walk(dirPath)
+ .filter { fileOrDir -> !Files.isDirectory(fileOrDir) }
+ .forEach { filePath ->
+ filePathToOutputPath.checkForDuplicatesAndSetFilePathToPathInsideJar(
+ dirPath.relativize(filePath),
+ filePath,
+ errors
+ )
+ }
+ }
+ }
+
+ check(errors.isEmpty()) { errors.joinToString("\n") }
+
+ ZipOutputStream(BufferedOutputStream(Files.newOutputStream(outputJar))).use { zipper ->
+ filePathToOutputPath.writeToStream(zipper)
+ }
+ }
+}