1# Copyright 2022 Google LLC. All rights reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the License); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Kotlin kt_jvm_compile API test.""" 16 17load("//kotlin:traverse_exports.bzl", "kt_traverse_exports") 18load("//kotlin:jvm_compile.bzl", "kt_jvm_compile") 19load("//kotlin:common.bzl", "common") 20load("//tests/analysis:util.bzl", "ONLY_FOR_ANALYSIS_TEST_TAGS", "create_dir", "create_file") 21load("//toolchains/kotlin_jvm:java_toolchains.bzl", "java_toolchains") 22load("//toolchains/kotlin_jvm:kt_jvm_toolchains.bzl", "kt_jvm_toolchains") 23load("@bazel_skylib//rules:build_test.bzl", "build_test") 24load(":assert_failure_test.bzl", "assert_failure_test") 25load("//:visibility.bzl", "RULES_KOTLIN") 26 27def _impl(ctx): 28 # As additional capabilites need to be tested, this rule should support 29 # additional fields/attributes. 30 result = kt_jvm_compile( 31 ctx, 32 output = ctx.outputs.jar, 33 srcs = ctx.files.srcs, 34 common_srcs = ctx.files.common_srcs, 35 deps = ctx.attr.deps, 36 plugins = [], 37 exported_plugins = [], 38 runtime_deps = [], 39 exports = ctx.attr.exports, 40 javacopts = [], 41 kotlincopts = [], 42 neverlink = False, 43 testonly = False, 44 android_lint_plugins = [], 45 manifest = None, 46 merged_manifest = None, 47 resource_files = [], 48 rule_family = ctx.attr.rule_family, 49 kt_toolchain = kt_jvm_toolchains.get(ctx), 50 java_toolchain = java_toolchains.get(ctx), 51 disable_lint_checks = [], 52 r_java = ctx.attr.r_java[JavaInfo] if ctx.attr.r_java else None, 53 ) 54 return [result.java_info] 55 56_kt_jvm_compile = rule( 57 implementation = _impl, 58 attrs = dict( 59 srcs = attr.label_list( 60 allow_files = True, 61 ), 62 common_srcs = attr.label_list( 63 allow_files = True, 64 ), 65 deps = attr.label_list( 66 aspects = [kt_traverse_exports.aspect], 67 providers = [JavaInfo], 68 ), 69 exports = attr.label_list( 70 aspects = [kt_traverse_exports.aspect], 71 providers = [JavaInfo], 72 ), 73 rule_family = attr.int( 74 default = common.RULE_FAMILY.UNKNOWN, 75 ), 76 r_java = attr.label( 77 providers = [JavaInfo], 78 ), 79 _java_toolchain = attr.label( 80 default = Label( 81 "@bazel_tools//tools/jdk:current_java_toolchain", 82 ), 83 ), 84 ), 85 fragments = ["java"], 86 outputs = dict( 87 jar = "lib%{name}.jar", 88 ), 89 toolchains = [kt_jvm_toolchains.type], 90) 91 92def _test_kt_jvm_compile_using_kt_jvm_compile_with_r_java(): 93 test_name = "kt_jvm_compile_using_kt_jvm_compile_with_r_java_test" 94 95 native.java_library( 96 name = "foo_resources", 97 srcs = [create_file( 98 name = test_name + "/java/com/foo/R.java", 99 content = """ 100package com.foo; 101 102public final class R { 103 public static final class string { 104 public static int a_string=0x00000001; 105 public static int b_string=0x00000002; 106 } 107} 108""", 109 )], 110 ) 111 112 _kt_jvm_compile( 113 name = "kt_jvm_compile_with_r_java", 114 srcs = [create_file( 115 name = test_name + "/AString.kt", 116 content = """ 117package test 118 119import com.foo.R.string.a_string 120 121fun aString(): String = "a_string=" + a_string 122""", 123 )], 124 r_java = ":foo_resources", 125 ) 126 127 _kt_jvm_compile( 128 name = "kt_jvm_compile_using_kt_jvm_compile_with_r_java", 129 srcs = [create_file( 130 name = test_name + "/ABString.kt", 131 content = """ 132package test 133 134import com.foo.R.string.b_string 135 136fun bString(): String = "b_string=" + b_string 137 138fun abString(): String = aString() + bString() 139""", 140 )], 141 deps = [":kt_jvm_compile_with_r_java"], 142 ) 143 144 # If a failure occurs, it will be at build time. 145 build_test( 146 name = test_name, 147 targets = [":kt_jvm_compile_using_kt_jvm_compile_with_r_java"], 148 ) 149 return test_name 150 151def _test_kt_jvm_compile_with_illegal_r_java(): 152 test_name = "kt_jvm_compile_with_illegal_r_java_test" 153 154 native.java_library( 155 name = "foo", 156 srcs = [create_file( 157 name = test_name + "/java/com/foo/Foo.java", 158 content = """ 159package com.foo; 160 161public class Foo {} 162""", 163 )], 164 ) 165 _kt_jvm_compile( 166 name = "kt_jvm_compile_with_illegal_r_java", 167 srcs = [create_file( 168 name = test_name + "/AString.kt", 169 content = """ 170package test 171 172import com.foo.Foo 173 174fun bar(): String = "Bar" 175""", 176 )], 177 tags = ONLY_FOR_ANALYSIS_TEST_TAGS, 178 r_java = ":foo", 179 ) 180 assert_failure_test( 181 name = test_name, 182 target_under_test = ":kt_jvm_compile_with_illegal_r_java", 183 msg_contains = "illegal dependency provided for r_java", 184 ) 185 return test_name 186 187def _test_kt_jvm_compile_with_r_java_as_first_dep(): 188 test_name = "kt_jvm_compile_with_r_java_as_first_dep_test" 189 190 # Note: The R from an android_library must be the first dependency in 191 # the classpath to prevent another libraries R from being used for 192 # compilation. If the ordering is incorrect, compiletime failures will 193 # occur as the depot relies on this ordering. 194 195 native.java_library( 196 name = "foo_with_symbol_resources", 197 srcs = [create_file( 198 name = test_name + "/with_symbol/java/com/foo/R.java", 199 content = """ 200package com.foo; 201 202public final class R { 203 public static final class string { 204 public static int a_string=0x00000001; 205 } 206} 207""", 208 )], 209 ) 210 211 native.java_library( 212 name = "foo_without_symbol_resources", 213 srcs = [create_file( 214 name = test_name + "/without_symbol/java/com/foo/R.java", 215 content = """ 216package com.foo; 217 218public final class R { 219 public static final class string { 220 } 221} 222""", 223 )], 224 ) 225 226 _kt_jvm_compile( 227 name = "kt_jvm_compile_with_r_java_as_first_dep", 228 srcs = [create_file( 229 name = test_name + "/AString.kt", 230 content = """ 231package test 232 233import com.foo.R.string.a_string 234 235fun aString(): String = "a_string=" + a_string 236""", 237 )], 238 r_java = ":foo_with_symbol_resources", 239 deps = [":foo_without_symbol_resources"], 240 ) 241 242 # If a failure occurs, it will be at build time. 243 build_test( 244 name = test_name, 245 targets = [":kt_jvm_compile_with_r_java_as_first_dep"], 246 ) 247 return test_name 248 249def _test_kt_jvm_compile_without_srcs_for_android(): 250 test_name = "kt_jvm_compile_without_srcs_for_android_test" 251 252 # This is a common case for rules like android_library where Kotlin sources 253 # could be empty, due to the rule being used for resource processing. For 254 # this scenario, historically, rules continue to produce empty Jars. 255 _kt_jvm_compile( 256 name = "kt_jvm_compile_without_srcs_for_android", 257 rule_family = common.RULE_FAMILY.ANDROID_LIBRARY, 258 ) 259 260 # If a failure occurs, it will be at build time. 261 build_test( 262 name = test_name, 263 targets = [":kt_jvm_compile_without_srcs_for_android"], 264 ) 265 return test_name 266 267def _test_kt_jvm_compile_without_srcs_for_jvm(): 268 test_name = "kt_jvm_compile_without_srcs_for_jvm_test" 269 270 _kt_jvm_compile( 271 name = "kt_jvm_compile_without_srcs_for_jvm", 272 srcs = [], 273 common_srcs = [], 274 exports = [], 275 tags = ONLY_FOR_ANALYSIS_TEST_TAGS, 276 ) 277 assert_failure_test( 278 name = test_name, 279 target_under_test = ":kt_jvm_compile_without_srcs_for_jvm", 280 msg_contains = "Expected one of (srcs, common_srcs, exports) is not empty", 281 ) 282 return test_name 283 284def _test_kt_jvm_compile_without_srcs_and_with_exports(): 285 test_name = "kt_jvm_compile_without_srcs_and_with_exports_test" 286 287 _kt_jvm_compile( 288 name = "bar_lib", 289 srcs = [create_file( 290 name = test_name + "/Bar.kt", 291 content = """ 292package test 293 294fun bar(): String = "Bar" 295""", 296 )], 297 ) 298 299 _kt_jvm_compile( 300 name = "kt_jvm_compile_without_srcs_and_with_exports", 301 exports = [":bar_lib"], 302 ) 303 304 _kt_jvm_compile( 305 name = "foo_bar_lib", 306 srcs = [create_file( 307 name = test_name + "/FooBar.kt", 308 content = """ 309package test 310 311fun fooBar(): String = "Foo" + bar() 312""", 313 )], 314 deps = [":kt_jvm_compile_without_srcs_and_with_exports"], 315 ) 316 317 # If a failure occurs, it will be at build time. 318 build_test( 319 name = test_name, 320 targets = [":foo_bar_lib"], 321 ) 322 return test_name 323 324def _test_kt_jvm_compile_unsupported_src_artifacts(): 325 test_name = "kt_jvm_compile_unsupported_src_artifacts_test" 326 327 kt_src = create_file( 328 name = test_name + "/src.kt", 329 content = "", 330 ) 331 kt_dir = create_dir( 332 name = test_name + "/kotlin", 333 subdir = "", 334 srcs = [create_file( 335 name = test_name + "/dir.kt", 336 content = "", 337 )], 338 ) 339 java_src = create_file( 340 name = test_name + "/src.java", 341 content = "", 342 ) 343 java_dir = create_dir( 344 name = test_name + "/java", 345 subdir = "", 346 srcs = [create_file( 347 name = test_name + "/dir.java", 348 content = "", 349 )], 350 ) 351 java_srcjar = create_file( 352 name = test_name + "/java.srcjar", 353 content = "", 354 ) 355 _kt_jvm_compile( 356 name = test_name + "_expected_lib", 357 srcs = [kt_src, kt_dir, java_src, java_dir, java_srcjar], 358 tags = ONLY_FOR_ANALYSIS_TEST_TAGS, 359 ) 360 361 unexpected_file = create_file( 362 name = test_name + "/src.unexpected", 363 content = "", 364 ) 365 _kt_jvm_compile( 366 name = test_name + "_unexpected_lib", 367 srcs = [unexpected_file], 368 deps = [test_name + "_expected_lib"], 369 tags = ONLY_FOR_ANALYSIS_TEST_TAGS, 370 ) 371 372 assert_failure_test( 373 name = test_name, 374 target_under_test = test_name + "_unexpected_lib", 375 msg_contains = "/src.unexpected", 376 ) 377 return test_name 378 379def test_suite(name = None): 380 native.test_suite( 381 name = name, 382 tests = [ 383 _test_kt_jvm_compile_unsupported_src_artifacts(), 384 _test_kt_jvm_compile_using_kt_jvm_compile_with_r_java(), 385 _test_kt_jvm_compile_with_illegal_r_java(), 386 _test_kt_jvm_compile_with_r_java_as_first_dep(), 387 _test_kt_jvm_compile_without_srcs_for_android(), 388 _test_kt_jvm_compile_without_srcs_for_jvm(), 389 _test_kt_jvm_compile_without_srcs_and_with_exports(), 390 ], 391 ) 392