392 lines
11 KiB
Python
392 lines
11 KiB
Python
# 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 kt_jvm_compile API test."""
|
|
|
|
load("//kotlin:traverse_exports.bzl", "kt_traverse_exports")
|
|
load("//kotlin:jvm_compile.bzl", "kt_jvm_compile")
|
|
load("//kotlin:common.bzl", "common")
|
|
load("//tests/analysis:util.bzl", "ONLY_FOR_ANALYSIS_TEST_TAGS", "create_dir", "create_file")
|
|
load("//toolchains/kotlin_jvm:java_toolchains.bzl", "java_toolchains")
|
|
load("//toolchains/kotlin_jvm:kt_jvm_toolchains.bzl", "kt_jvm_toolchains")
|
|
load("@bazel_skylib//rules:build_test.bzl", "build_test")
|
|
load(":assert_failure_test.bzl", "assert_failure_test")
|
|
load("//:visibility.bzl", "RULES_KOTLIN")
|
|
|
|
def _impl(ctx):
|
|
# As additional capabilites need to be tested, this rule should support
|
|
# additional fields/attributes.
|
|
result = kt_jvm_compile(
|
|
ctx,
|
|
output = ctx.outputs.jar,
|
|
srcs = ctx.files.srcs,
|
|
common_srcs = ctx.files.common_srcs,
|
|
deps = ctx.attr.deps,
|
|
plugins = [],
|
|
exported_plugins = [],
|
|
runtime_deps = [],
|
|
exports = ctx.attr.exports,
|
|
javacopts = [],
|
|
kotlincopts = [],
|
|
neverlink = False,
|
|
testonly = False,
|
|
android_lint_plugins = [],
|
|
manifest = None,
|
|
merged_manifest = None,
|
|
resource_files = [],
|
|
rule_family = ctx.attr.rule_family,
|
|
kt_toolchain = kt_jvm_toolchains.get(ctx),
|
|
java_toolchain = java_toolchains.get(ctx),
|
|
disable_lint_checks = [],
|
|
r_java = ctx.attr.r_java[JavaInfo] if ctx.attr.r_java else None,
|
|
)
|
|
return [result.java_info]
|
|
|
|
_kt_jvm_compile = rule(
|
|
implementation = _impl,
|
|
attrs = dict(
|
|
srcs = attr.label_list(
|
|
allow_files = True,
|
|
),
|
|
common_srcs = attr.label_list(
|
|
allow_files = True,
|
|
),
|
|
deps = attr.label_list(
|
|
aspects = [kt_traverse_exports.aspect],
|
|
providers = [JavaInfo],
|
|
),
|
|
exports = attr.label_list(
|
|
aspects = [kt_traverse_exports.aspect],
|
|
providers = [JavaInfo],
|
|
),
|
|
rule_family = attr.int(
|
|
default = common.RULE_FAMILY.UNKNOWN,
|
|
),
|
|
r_java = attr.label(
|
|
providers = [JavaInfo],
|
|
),
|
|
_java_toolchain = attr.label(
|
|
default = Label(
|
|
"@bazel_tools//tools/jdk:current_java_toolchain",
|
|
),
|
|
),
|
|
),
|
|
fragments = ["java"],
|
|
outputs = dict(
|
|
jar = "lib%{name}.jar",
|
|
),
|
|
toolchains = [kt_jvm_toolchains.type],
|
|
)
|
|
|
|
def _test_kt_jvm_compile_using_kt_jvm_compile_with_r_java():
|
|
test_name = "kt_jvm_compile_using_kt_jvm_compile_with_r_java_test"
|
|
|
|
native.java_library(
|
|
name = "foo_resources",
|
|
srcs = [create_file(
|
|
name = test_name + "/java/com/foo/R.java",
|
|
content = """
|
|
package com.foo;
|
|
|
|
public final class R {
|
|
public static final class string {
|
|
public static int a_string=0x00000001;
|
|
public static int b_string=0x00000002;
|
|
}
|
|
}
|
|
""",
|
|
)],
|
|
)
|
|
|
|
_kt_jvm_compile(
|
|
name = "kt_jvm_compile_with_r_java",
|
|
srcs = [create_file(
|
|
name = test_name + "/AString.kt",
|
|
content = """
|
|
package test
|
|
|
|
import com.foo.R.string.a_string
|
|
|
|
fun aString(): String = "a_string=" + a_string
|
|
""",
|
|
)],
|
|
r_java = ":foo_resources",
|
|
)
|
|
|
|
_kt_jvm_compile(
|
|
name = "kt_jvm_compile_using_kt_jvm_compile_with_r_java",
|
|
srcs = [create_file(
|
|
name = test_name + "/ABString.kt",
|
|
content = """
|
|
package test
|
|
|
|
import com.foo.R.string.b_string
|
|
|
|
fun bString(): String = "b_string=" + b_string
|
|
|
|
fun abString(): String = aString() + bString()
|
|
""",
|
|
)],
|
|
deps = [":kt_jvm_compile_with_r_java"],
|
|
)
|
|
|
|
# If a failure occurs, it will be at build time.
|
|
build_test(
|
|
name = test_name,
|
|
targets = [":kt_jvm_compile_using_kt_jvm_compile_with_r_java"],
|
|
)
|
|
return test_name
|
|
|
|
def _test_kt_jvm_compile_with_illegal_r_java():
|
|
test_name = "kt_jvm_compile_with_illegal_r_java_test"
|
|
|
|
native.java_library(
|
|
name = "foo",
|
|
srcs = [create_file(
|
|
name = test_name + "/java/com/foo/Foo.java",
|
|
content = """
|
|
package com.foo;
|
|
|
|
public class Foo {}
|
|
""",
|
|
)],
|
|
)
|
|
_kt_jvm_compile(
|
|
name = "kt_jvm_compile_with_illegal_r_java",
|
|
srcs = [create_file(
|
|
name = test_name + "/AString.kt",
|
|
content = """
|
|
package test
|
|
|
|
import com.foo.Foo
|
|
|
|
fun bar(): String = "Bar"
|
|
""",
|
|
)],
|
|
tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
|
|
r_java = ":foo",
|
|
)
|
|
assert_failure_test(
|
|
name = test_name,
|
|
target_under_test = ":kt_jvm_compile_with_illegal_r_java",
|
|
msg_contains = "illegal dependency provided for r_java",
|
|
)
|
|
return test_name
|
|
|
|
def _test_kt_jvm_compile_with_r_java_as_first_dep():
|
|
test_name = "kt_jvm_compile_with_r_java_as_first_dep_test"
|
|
|
|
# Note: The R from an android_library must be the first dependency in
|
|
# the classpath to prevent another libraries R from being used for
|
|
# compilation. If the ordering is incorrect, compiletime failures will
|
|
# occur as the depot relies on this ordering.
|
|
|
|
native.java_library(
|
|
name = "foo_with_symbol_resources",
|
|
srcs = [create_file(
|
|
name = test_name + "/with_symbol/java/com/foo/R.java",
|
|
content = """
|
|
package com.foo;
|
|
|
|
public final class R {
|
|
public static final class string {
|
|
public static int a_string=0x00000001;
|
|
}
|
|
}
|
|
""",
|
|
)],
|
|
)
|
|
|
|
native.java_library(
|
|
name = "foo_without_symbol_resources",
|
|
srcs = [create_file(
|
|
name = test_name + "/without_symbol/java/com/foo/R.java",
|
|
content = """
|
|
package com.foo;
|
|
|
|
public final class R {
|
|
public static final class string {
|
|
}
|
|
}
|
|
""",
|
|
)],
|
|
)
|
|
|
|
_kt_jvm_compile(
|
|
name = "kt_jvm_compile_with_r_java_as_first_dep",
|
|
srcs = [create_file(
|
|
name = test_name + "/AString.kt",
|
|
content = """
|
|
package test
|
|
|
|
import com.foo.R.string.a_string
|
|
|
|
fun aString(): String = "a_string=" + a_string
|
|
""",
|
|
)],
|
|
r_java = ":foo_with_symbol_resources",
|
|
deps = [":foo_without_symbol_resources"],
|
|
)
|
|
|
|
# If a failure occurs, it will be at build time.
|
|
build_test(
|
|
name = test_name,
|
|
targets = [":kt_jvm_compile_with_r_java_as_first_dep"],
|
|
)
|
|
return test_name
|
|
|
|
def _test_kt_jvm_compile_without_srcs_for_android():
|
|
test_name = "kt_jvm_compile_without_srcs_for_android_test"
|
|
|
|
# This is a common case for rules like android_library where Kotlin sources
|
|
# could be empty, due to the rule being used for resource processing. For
|
|
# this scenario, historically, rules continue to produce empty Jars.
|
|
_kt_jvm_compile(
|
|
name = "kt_jvm_compile_without_srcs_for_android",
|
|
rule_family = common.RULE_FAMILY.ANDROID_LIBRARY,
|
|
)
|
|
|
|
# If a failure occurs, it will be at build time.
|
|
build_test(
|
|
name = test_name,
|
|
targets = [":kt_jvm_compile_without_srcs_for_android"],
|
|
)
|
|
return test_name
|
|
|
|
def _test_kt_jvm_compile_without_srcs_for_jvm():
|
|
test_name = "kt_jvm_compile_without_srcs_for_jvm_test"
|
|
|
|
_kt_jvm_compile(
|
|
name = "kt_jvm_compile_without_srcs_for_jvm",
|
|
srcs = [],
|
|
common_srcs = [],
|
|
exports = [],
|
|
tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
|
|
)
|
|
assert_failure_test(
|
|
name = test_name,
|
|
target_under_test = ":kt_jvm_compile_without_srcs_for_jvm",
|
|
msg_contains = "Expected one of (srcs, common_srcs, exports) is not empty",
|
|
)
|
|
return test_name
|
|
|
|
def _test_kt_jvm_compile_without_srcs_and_with_exports():
|
|
test_name = "kt_jvm_compile_without_srcs_and_with_exports_test"
|
|
|
|
_kt_jvm_compile(
|
|
name = "bar_lib",
|
|
srcs = [create_file(
|
|
name = test_name + "/Bar.kt",
|
|
content = """
|
|
package test
|
|
|
|
fun bar(): String = "Bar"
|
|
""",
|
|
)],
|
|
)
|
|
|
|
_kt_jvm_compile(
|
|
name = "kt_jvm_compile_without_srcs_and_with_exports",
|
|
exports = [":bar_lib"],
|
|
)
|
|
|
|
_kt_jvm_compile(
|
|
name = "foo_bar_lib",
|
|
srcs = [create_file(
|
|
name = test_name + "/FooBar.kt",
|
|
content = """
|
|
package test
|
|
|
|
fun fooBar(): String = "Foo" + bar()
|
|
""",
|
|
)],
|
|
deps = [":kt_jvm_compile_without_srcs_and_with_exports"],
|
|
)
|
|
|
|
# If a failure occurs, it will be at build time.
|
|
build_test(
|
|
name = test_name,
|
|
targets = [":foo_bar_lib"],
|
|
)
|
|
return test_name
|
|
|
|
def _test_kt_jvm_compile_unsupported_src_artifacts():
|
|
test_name = "kt_jvm_compile_unsupported_src_artifacts_test"
|
|
|
|
kt_src = create_file(
|
|
name = test_name + "/src.kt",
|
|
content = "",
|
|
)
|
|
kt_dir = create_dir(
|
|
name = test_name + "/kotlin",
|
|
subdir = "",
|
|
srcs = [create_file(
|
|
name = test_name + "/dir.kt",
|
|
content = "",
|
|
)],
|
|
)
|
|
java_src = create_file(
|
|
name = test_name + "/src.java",
|
|
content = "",
|
|
)
|
|
java_dir = create_dir(
|
|
name = test_name + "/java",
|
|
subdir = "",
|
|
srcs = [create_file(
|
|
name = test_name + "/dir.java",
|
|
content = "",
|
|
)],
|
|
)
|
|
java_srcjar = create_file(
|
|
name = test_name + "/java.srcjar",
|
|
content = "",
|
|
)
|
|
_kt_jvm_compile(
|
|
name = test_name + "_expected_lib",
|
|
srcs = [kt_src, kt_dir, java_src, java_dir, java_srcjar],
|
|
tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
|
|
)
|
|
|
|
unexpected_file = create_file(
|
|
name = test_name + "/src.unexpected",
|
|
content = "",
|
|
)
|
|
_kt_jvm_compile(
|
|
name = test_name + "_unexpected_lib",
|
|
srcs = [unexpected_file],
|
|
deps = [test_name + "_expected_lib"],
|
|
tags = ONLY_FOR_ANALYSIS_TEST_TAGS,
|
|
)
|
|
|
|
assert_failure_test(
|
|
name = test_name,
|
|
target_under_test = test_name + "_unexpected_lib",
|
|
msg_contains = "/src.unexpected",
|
|
)
|
|
return test_name
|
|
|
|
def test_suite(name = None):
|
|
native.test_suite(
|
|
name = name,
|
|
tests = [
|
|
_test_kt_jvm_compile_unsupported_src_artifacts(),
|
|
_test_kt_jvm_compile_using_kt_jvm_compile_with_r_java(),
|
|
_test_kt_jvm_compile_with_illegal_r_java(),
|
|
_test_kt_jvm_compile_with_r_java_as_first_dep(),
|
|
_test_kt_jvm_compile_without_srcs_for_android(),
|
|
_test_kt_jvm_compile_without_srcs_for_jvm(),
|
|
_test_kt_jvm_compile_without_srcs_and_with_exports(),
|
|
],
|
|
)
|