From ffcd2b2e7ea787eca1ab5bf09f296b06f9fe933f Mon Sep 17 00:00:00 2001 From: Corbin McNeely-Smith <58151731+restingbull@users.noreply.github.com> Date: Thu, 27 Feb 2020 10:16:52 -0500 Subject: [PATCH] Cleanup src tree (#288) * Move CompilationTaskContext to toolchain, as it doesn't really belong in utils. * Move KotlinCompilerPluginArgsEncoder to toolchain. Temporary placement, new location TBD * Isolate the utils package * Move toolchain into a separate compilation unit. Causes some issues with inlining. * Split apart test packages. * Split apart test packages. * Split apart test packages. * add bazel version for development * factor out JvmCompilationTask extensions to reuse in abi generation * move compiler to source package. add .bazelversion for development --- .bazelproject | 8 +- .bazelrc | 2 +- .bazelversion | 1 + src/main/kotlin/BUILD | 17 +- src/main/kotlin/io/bazel/kotlin/builder/BUILD | 24 +- .../builder/KotlinBuilderComponent.java | 2 +- .../io/bazel/kotlin/builder/tasks/BUILD.bazel | 34 +++ .../kotlin/builder/tasks/KotlinBuilder.kt | 1 + .../builder/tasks/js/Kotlin2JsTaskExecutor.kt | 3 +- .../kotlin/builder/tasks/jvm/JavaCompiler.kt | 2 +- .../tasks/jvm/KotlinJvmTaskExecutor.kt | 211 ++-------------- .../builder/tasks/jvm/compilation_task.kt | 236 ++++++++++++++++++ .../kotlin/builder/toolchain/BUILD.bazel | 30 +++ .../CompilationTaskContext.kt | 10 +- .../KotlinCompilerPluginArgsEncoder.kt | 4 +- .../builder/toolchain/KotlinToolchain.kt | 200 +++++++-------- .../io/bazel/kotlin/builder/utils/BUILD.bazel | 31 +++ .../io/bazel/kotlin/compiler/BUILD.bazel | 27 ++ src/test/kotlin/io/bazel/kotlin/builder/BUILD | 59 +---- .../builder/KotlinAbstractTestBuilder.java | 2 +- .../io/bazel/kotlin/builder/tasks/BUILD.bazel | 56 +++++ .../io/bazel/kotlin/builder/utils/BUILD.bazel | 25 ++ 22 files changed, 584 insertions(+), 401 deletions(-) create mode 100644 .bazelversion create mode 100644 src/main/kotlin/io/bazel/kotlin/builder/tasks/BUILD.bazel create mode 100644 src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/compilation_task.kt create mode 100644 src/main/kotlin/io/bazel/kotlin/builder/toolchain/BUILD.bazel rename src/main/kotlin/io/bazel/kotlin/builder/{utils => toolchain}/CompilationTaskContext.kt (95%) rename src/main/kotlin/io/bazel/kotlin/builder/{utils => toolchain}/KotlinCompilerPluginArgsEncoder.kt (98%) create mode 100644 src/main/kotlin/io/bazel/kotlin/builder/utils/BUILD.bazel create mode 100644 src/main/kotlin/io/bazel/kotlin/compiler/BUILD.bazel create mode 100644 src/test/kotlin/io/bazel/kotlin/builder/tasks/BUILD.bazel create mode 100644 src/test/kotlin/io/bazel/kotlin/builder/utils/BUILD.bazel diff --git a/.bazelproject b/.bazelproject index b5daf792e..0be2b5a76 100644 --- a/.bazelproject +++ b/.bazelproject @@ -26,8 +26,10 @@ targets: //examples/dagger/... # These targets are built for the ide only. Primary purpose is to ensure the builder can build the targets, but it's # also a good way of testing the intellij plugin. - //src/main/kotlin/io/bazel/kotlin/builder:builder_kt_for_ide - //src/main/kotlin:compiler_lib_for_ide + //src/main/kotlin/io/bazel/kotlin/builder/tasks:tasks_for_ide + //src/main/kotlin/io/bazel/kotlin/builder/utils:utils_for_ide + //src/main/kotlin/io/bazel/kotlin/builder/toolchain:toolchain_for_ide + //src/main/kotlin/io/bazel/kotlin/compiler:compiler_for_ide test_sources: src/test/* @@ -36,4 +38,4 @@ additional_languages: kotlin import_run_configurations: - src/test/Bazel_all_local_tests.xml \ No newline at end of file + src/test/Bazel_all_local_tests.xml diff --git a/.bazelrc b/.bazelrc index e75318b3a..6858b6449 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,4 +1,4 @@ build --strategy=KotlinCompile=worker -build --test_output=errors +build --test_output=all build --verbose_failures diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 000000000..227cea215 --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +2.0.0 diff --git a/src/main/kotlin/BUILD b/src/main/kotlin/BUILD index da083be62..7fd6f1c2f 100644 --- a/src/main/kotlin/BUILD +++ b/src/main/kotlin/BUILD @@ -12,23 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. load("@rules_java//java:defs.bzl", "java_binary") -load("//src/main/kotlin:bootstrap.bzl", "kt_bootstrap_library") load("//kotlin:kotlin.bzl", "kt_jvm_library") load("//third_party:jarjar.bzl", "jar_jar") load("//kotlin/internal/utils:packager.bzl", "release_archive") -# The compiler library, this is co-located in the kotlin compiler classloader. -kt_bootstrap_library( - name = "compiler_lib", - srcs = glob(["io/bazel/kotlin/compiler/*.kt"]), - neverlink_deps = [ - "@com_github_jetbrains_kotlin//:kotlin-compiler", - "@com_github_jetbrains_kotlin//:kotlin-annotation-processing", - "@com_github_jetbrains_kotlin//:kotlin-script-runtime", - ], - visibility = ["//src/test/kotlin/io/bazel/kotlin/builder:__subpackages__"], -) - java_binary( name = "builder_raw", create_executable = False, @@ -46,7 +33,7 @@ jar_jar( java_binary( name = "builder", data = [ - ":compiler_lib.jar", + "//src/main/kotlin/io/bazel/kotlin/compiler:compiler", "@com_github_jetbrains_kotlin//:lib/kotlin-compiler.jar", ], jvm_flags = [ @@ -63,7 +50,7 @@ java_binary( release_archive( name = "pkg", srcs = [ - ":compiler_lib.jar", + "//src/main/kotlin/io/bazel/kotlin/compiler:compiler", ], package_dir = "src/main/kotlin", # explicitly set the package directory, as there are no parent release_archives. src_map = { diff --git a/src/main/kotlin/io/bazel/kotlin/builder/BUILD b/src/main/kotlin/io/bazel/kotlin/builder/BUILD index 385295d17..527161266 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/BUILD +++ b/src/main/kotlin/io/bazel/kotlin/builder/BUILD @@ -12,37 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. load("@rules_java//java:defs.bzl", "java_library") -load("//src/main/kotlin:bootstrap.bzl", "kt_bootstrap_library") - -kt_bootstrap_library( - name = "builder_kt", - srcs = glob([ - "toolchain/*.kt", - "tasks/**/*.kt", - "utils/**/*.kt", - ]), - deps = [ - "//src/main/protobuf:deps_java_proto", - "//src/main/protobuf:kotlin_model_java_proto", - "//src/main/protobuf:worker_protocol_java_proto", - "@com_github_jetbrains_kotlin//:kotlin-preloader", - "@kotlin_rules_maven//:com_google_protobuf_protobuf_java", - "@kotlin_rules_maven//:com_google_protobuf_protobuf_java_util", - "@kotlin_rules_maven//:javax_inject_javax_inject", - ], -) java_library( name = "builder", srcs = glob(["*.java"]), visibility = ["//src:__subpackages__"], - exports = [":builder_kt"], runtime_deps = [ "@com_github_jetbrains_kotlin//:kotlin-stdlib-jdk7", "@com_github_jetbrains_kotlin//:kotlin-stdlib-jdk8", ], deps = [ - ":builder_kt", "//src/main/protobuf:deps_java_proto", "//src/main/protobuf:kotlin_model_java_proto", "//src/main/protobuf:worker_protocol_java_proto", @@ -50,5 +29,8 @@ java_library( "@com_github_jetbrains_kotlin//:annotations", "@com_github_jetbrains_kotlin//:kotlin-stdlib", "@kotlin_rules_maven//:javax_inject_javax_inject", + "//src/main/kotlin/io/bazel/kotlin/builder/utils:utils", + "//src/main/kotlin/io/bazel/kotlin/builder/toolchain:toolchain", + "//src/main/kotlin/io/bazel/kotlin/builder/tasks:tasks", ], ) diff --git a/src/main/kotlin/io/bazel/kotlin/builder/KotlinBuilderComponent.java b/src/main/kotlin/io/bazel/kotlin/builder/KotlinBuilderComponent.java index 88dc8d390..a3f0daac3 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/KotlinBuilderComponent.java +++ b/src/main/kotlin/io/bazel/kotlin/builder/KotlinBuilderComponent.java @@ -23,7 +23,7 @@ import io.bazel.kotlin.builder.tasks.js.Kotlin2JsTaskExecutor; import io.bazel.kotlin.builder.tasks.jvm.KotlinJvmTaskExecutor; import io.bazel.kotlin.builder.toolchain.KotlinToolchain; -import io.bazel.kotlin.builder.utils.KotlinCompilerPluginArgsEncoder; +import io.bazel.kotlin.builder.toolchain.KotlinCompilerPluginArgsEncoder; import javax.inject.Singleton; import java.io.PrintStream; diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/BUILD.bazel b/src/main/kotlin/io/bazel/kotlin/builder/tasks/BUILD.bazel new file mode 100644 index 000000000..d8c7d501a --- /dev/null +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/BUILD.bazel @@ -0,0 +1,34 @@ +# Copyright 2020 The Bazel Authors. 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("//src/main/kotlin:bootstrap.bzl", "kt_bootstrap_library") + +kt_bootstrap_library( + name = "tasks", + srcs = glob([ + "**/*.kt", + ]), + visibility = ["//src:__subpackages__"], + deps = [ + "//src/main/protobuf:deps_java_proto", + "//src/main/protobuf:kotlin_model_java_proto", + "//src/main/protobuf:worker_protocol_java_proto", + "@com_github_jetbrains_kotlin//:kotlin-preloader", + "@kotlin_rules_maven//:com_google_protobuf_protobuf_java", + "@kotlin_rules_maven//:com_google_protobuf_protobuf_java_util", + "@kotlin_rules_maven//:javax_inject_javax_inject", + "//src/main/kotlin/io/bazel/kotlin/builder/utils:utils", + "//src/main/kotlin/io/bazel/kotlin/builder/toolchain:toolchain", + ], +) \ No newline at end of file diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt index 339699f51..3cc5c1637 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt @@ -18,6 +18,7 @@ package io.bazel.kotlin.builder.tasks import io.bazel.kotlin.builder.tasks.js.Kotlin2JsTaskExecutor import io.bazel.kotlin.builder.tasks.jvm.KotlinJvmTaskExecutor import io.bazel.kotlin.builder.toolchain.CompilationStatusException +import io.bazel.kotlin.builder.toolchain.CompilationTaskContext import io.bazel.kotlin.builder.utils.* import io.bazel.kotlin.model.* import java.io.PrintStream diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/js/Kotlin2JsTaskExecutor.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/js/Kotlin2JsTaskExecutor.kt index 028130b24..fa5dc45e8 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/js/Kotlin2JsTaskExecutor.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/js/Kotlin2JsTaskExecutor.kt @@ -2,12 +2,11 @@ package io.bazel.kotlin.builder.tasks.js import io.bazel.kotlin.builder.toolchain.CompilationException import io.bazel.kotlin.builder.toolchain.KotlinToolchain -import io.bazel.kotlin.builder.utils.CompilationTaskContext +import io.bazel.kotlin.builder.toolchain.CompilationTaskContext import io.bazel.kotlin.builder.utils.addAll import io.bazel.kotlin.builder.utils.jars.JarCreator import io.bazel.kotlin.builder.utils.jars.SourceJarCreator import io.bazel.kotlin.builder.utils.resolveTwinVerified -import io.bazel.kotlin.builder.utils.verifiedPath import io.bazel.kotlin.model.JsCompilationTask import java.io.FileOutputStream import java.nio.file.Files diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/JavaCompiler.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/JavaCompiler.kt index 606f644fd..d006026fa 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/JavaCompiler.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/JavaCompiler.kt @@ -16,7 +16,7 @@ package io.bazel.kotlin.builder.tasks.jvm import io.bazel.kotlin.builder.toolchain.KotlinToolchain -import io.bazel.kotlin.builder.utils.CompilationTaskContext +import io.bazel.kotlin.builder.toolchain.CompilationTaskContext import io.bazel.kotlin.builder.utils.addAll import io.bazel.kotlin.builder.utils.joinedClasspath import io.bazel.kotlin.model.JvmCompilationTask diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/KotlinJvmTaskExecutor.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/KotlinJvmTaskExecutor.kt index c326fd977..293520725 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/KotlinJvmTaskExecutor.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/KotlinJvmTaskExecutor.kt @@ -15,16 +15,10 @@ */ package io.bazel.kotlin.builder.tasks.jvm -import io.bazel.kotlin.builder.toolchain.CompilationStatusException +import io.bazel.kotlin.builder.toolchain.CompilationTaskContext +import io.bazel.kotlin.builder.toolchain.KotlinCompilerPluginArgsEncoder import io.bazel.kotlin.builder.toolchain.KotlinToolchain -import io.bazel.kotlin.builder.utils.* -import io.bazel.kotlin.builder.utils.jars.JarCreator -import io.bazel.kotlin.builder.utils.jars.SourceJarCreator -import io.bazel.kotlin.builder.utils.jars.SourceJarExtractor import io.bazel.kotlin.model.JvmCompilationTask -import java.io.File -import java.nio.file.Files -import java.nio.file.Paths import javax.inject.Inject import javax.inject.Singleton @@ -36,196 +30,19 @@ const val X_FRIENDS_PATH_SEPARATOR = "," @Singleton class KotlinJvmTaskExecutor @Inject internal constructor( - private val compiler: KotlinToolchain.KotlincInvoker, - private val pluginArgsEncoder: KotlinCompilerPluginArgsEncoder, - private val javaCompiler: JavaCompiler, - private val jDepsGenerator: JDepsGenerator + private val compiler: KotlinToolchain.KotlincInvoker, + private val pluginArgsEncoder: KotlinCompilerPluginArgsEncoder, + private val javaCompiler: JavaCompiler, + private val jDepsGenerator: JDepsGenerator ) { - fun execute(context: CompilationTaskContext, task: JvmCompilationTask) { - val preprocessedTask = task.preProcessingSteps(context) - context.execute("compile classes") { preprocessedTask.compileAll(context) } - context.execute("create jar") { preprocessedTask.createOutputJar() } - context.execute("produce src jar") { preprocessedTask.produceSourceJar() } - context.execute("generate jdeps") { jDepsGenerator.generateJDeps(preprocessedTask) } + fun execute(context: CompilationTaskContext, task: JvmCompilationTask) { + val preprocessedTask = task.preProcessingSteps(context, pluginArgsEncoder, compiler) + context.execute("compile classes") { + preprocessedTask.compileAll(context, compiler, javaCompiler) } - private fun JvmCompilationTask.preProcessingSteps(context: CompilationTaskContext): JvmCompilationTask { - ensureDirectories( - directories.temp, - directories.generatedSources, - directories.generatedClasses - ) - val taskWithAdditionalSources = context.execute("expand sources") { expandWithSourceJarSources() } - return context.execute({ - "kapt (${inputs.processorsList.joinToString(", ")})" - }) { taskWithAdditionalSources.runAnnotationProcessors(context) } - } - - private fun JvmCompilationTask.produceSourceJar() { - Paths.get(outputs.srcjar).also { sourceJarPath -> - Files.createFile(sourceJarPath) - SourceJarCreator( - sourceJarPath - ).also { creator -> - // This check asserts that source jars were unpacked if present. - check( - inputs.sourceJarsList.isEmpty() || - Files.exists(Paths.get(directories.temp).resolve("_srcjars")) - ) - listOf( - // Any (input) source jars should already have been expanded so do not add them here. - inputs.javaSourcesList.stream(), - inputs.kotlinSourcesList.stream() - ).stream() - .flatMap { it.map { p -> Paths.get(p) } } - .also { creator.addSources(it) } - creator.execute() - } - } - } - - private fun JvmCompilationTask.runAnnotationProcessor( - context: CompilationTaskContext, - printOnSuccess: Boolean = true - ): List { - check(inputs.processorsList.isNotEmpty()) { "method called without annotation processors" } - return getCommonArgs().let { args -> - args.addAll(pluginArgsEncoder.encode(context, this)) - args.addAll(inputs.kotlinSourcesList) - args.addAll(inputs.javaSourcesList) - context.executeCompilerTask(args, compiler::compile, printOnSuccess = printOnSuccess) - } - } - - /** - * Return a list with the common arguments. - */ - private fun JvmCompilationTask.getCommonArgs(): MutableList { - val args = mutableListOf() - val friendPaths = info.friendPathsList.map { Paths.get(it).toAbsolutePath() } - val cp = inputs.joinedClasspath - .split(File.pathSeparator) - .map { Paths.get(it).toAbsolutePath() } - .joinToString(File.pathSeparator) - args.addAll( - "-cp", cp, - "-api-version", info.toolchainInfo.common.apiVersion, - "-language-version", info.toolchainInfo.common.languageVersion, - "-jvm-target", info.toolchainInfo.jvm.jvmTarget, - "-Xfriend-paths=${friendPaths.joinToString(X_FRIENDS_PATH_SEPARATOR)}" - ) - args - .addAll("-module-name", info.moduleName) - .addAll("-d", directories.classes) - - info.passthroughFlags?.takeIf { it.isNotBlank() }?.also { args.addAll(it.split(" ")) } - return args - } - - private fun JvmCompilationTask.runAnnotationProcessors( - context: CompilationTaskContext - ): JvmCompilationTask = - if (inputs.processorsList.isEmpty()) { - this - } else { - runAnnotationProcessor(context, printOnSuccess = !context.isTracing).let { outputLines -> - // if tracing is enabled the output should be formatted in a special way, if we aren't tracing then any - // compiler output would make it's way to the console as is. - if (context.isTracing) { - context.printLines("kapt output", outputLines) - } - expandWithGeneratedSources() - } - } - - /** - * Produce the primary output jar. - */ - private fun JvmCompilationTask.createOutputJar() = - JarCreator( - path = Paths.get(outputs.jar), - normalize = true, - verbose = false - ).also { - it.addDirectory(Paths.get(directories.classes)) - it.addDirectory(Paths.get(directories.generatedClasses)) - it.setJarOwner(info.label, info.bazelRuleKind) - it.execute() - } - - private fun JvmCompilationTask.compileAll(context: CompilationTaskContext) { - ensureDirectories( - directories.classes - ) - var kotlinError: CompilationStatusException? = null - var result: List? = null - context.execute("kotlinc") { - result = try { - compileKotlin(context, printOnFail = false) - } catch (ex: CompilationStatusException) { - kotlinError = ex - ex.lines - } - } - try { - context.execute("javac") { javaCompiler.compile(context, this) } - } finally { - checkNotNull(result).also(context::printCompilerOutput) - kotlinError?.also { throw it } - } - } - - /** - * Compiles Kotlin sources to classes. Does not compile Java sources. - */ - private fun JvmCompilationTask.compileKotlin(context: CompilationTaskContext, printOnFail: Boolean = true) = - getCommonArgs().let { args -> - args.addAll(inputs.javaSourcesList) - args.addAll(inputs.kotlinSourcesList) - context.executeCompilerTask(args, compiler::compile, printOnFail = printOnFail) - } - - /** - * If any srcjars were provided expand the jars sources and create a new [JvmCompilationTask] with the - * Java and Kotlin sources merged in. - */ - private fun JvmCompilationTask.expandWithSourceJarSources(): JvmCompilationTask = - if (inputs.sourceJarsList.isEmpty()) - this - else expandWithSources( - SourceJarExtractor( - destDir = Paths.get(directories.temp).resolve("_srcjars"), - fileMatcher = IS_JVM_SOURCE_FILE - ).also { - it.jarFiles.addAll(inputs.sourceJarsList.map { p -> Paths.get(p) }) - it.execute() - }.sourcesList.iterator() - ) + context.execute("create jar") { preprocessedTask.createOutputJar() } + context.execute("produce src jar") { preprocessedTask.produceSourceJar() } + context.execute("generate jdeps") { jDepsGenerator.generateJDeps(preprocessedTask) } + } } - -/** - * Create a new [JvmCompilationTask] with sources found in the generatedSources directory. This should be run after - * annotation processors have been run. - */ -fun JvmCompilationTask.expandWithGeneratedSources(): JvmCompilationTask = - expandWithSources( - File(directories.generatedSources).walkTopDown() - .filter { it.isFile && IS_JVM_SOURCE_FILE.test(it.name) } - .map { it.path } - .iterator() - ) - -fun JvmCompilationTask.expandWithSources(sources: Iterator): JvmCompilationTask = - updateBuilder { builder -> - sources.partitionJvmSources( - { builder.inputsBuilder.addKotlinSources(it) }, - { builder.inputsBuilder.addJavaSources(it) }) - } - -fun JvmCompilationTask.updateBuilder( - block: (JvmCompilationTask.Builder) -> Unit -): JvmCompilationTask = - toBuilder().let { - block(it) - it.build() - } \ No newline at end of file diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/compilation_task.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/compilation_task.kt new file mode 100644 index 000000000..d9dcbfb2f --- /dev/null +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/compilation_task.kt @@ -0,0 +1,236 @@ +/* + * Copyright 2020 The Bazel Authors. 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. + */ + +// Provides extensions for the JvmCompilationTask protocol buffer. +package io.bazel.kotlin.builder.tasks.jvm + +import io.bazel.kotlin.builder.toolchain.CompilationStatusException +import io.bazel.kotlin.builder.toolchain.CompilationTaskContext +import io.bazel.kotlin.builder.toolchain.KotlinCompilerPluginArgsEncoder +import io.bazel.kotlin.builder.toolchain.KotlinToolchain +import io.bazel.kotlin.builder.utils.IS_JVM_SOURCE_FILE +import io.bazel.kotlin.builder.utils.addAll +import io.bazel.kotlin.builder.utils.bazelRuleKind +import io.bazel.kotlin.builder.utils.ensureDirectories +import io.bazel.kotlin.builder.utils.jars.JarCreator +import io.bazel.kotlin.builder.utils.jars.SourceJarCreator +import io.bazel.kotlin.builder.utils.jars.SourceJarExtractor +import io.bazel.kotlin.builder.utils.joinedClasspath +import io.bazel.kotlin.builder.utils.partitionJvmSources +import io.bazel.kotlin.model.JvmCompilationTask +import java.io.File +import java.nio.file.Files +import java.nio.file.Paths + +/** + * Return a list with the common arguments. + */ +internal fun JvmCompilationTask.getCommonArgs(): MutableList { + val args = mutableListOf() + val friendPaths = info.friendPathsList.map { Paths.get(it).toAbsolutePath() } + val cp = inputs.joinedClasspath + .split(File.pathSeparator) + .map { Paths.get(it).toAbsolutePath() } + .joinToString(File.pathSeparator) + args.addAll( + "-cp", cp, + "-api-version", info.toolchainInfo.common.apiVersion, + "-language-version", info.toolchainInfo.common.languageVersion, + "-jvm-target", info.toolchainInfo.jvm.jvmTarget, + "-Xfriend-paths=${friendPaths.joinToString(X_FRIENDS_PATH_SEPARATOR)}" + ) + args + .addAll("-module-name", info.moduleName) + .addAll("-d", directories.classes) + + info.passthroughFlags?.takeIf { it.isNotBlank() }?.also { args.addAll(it.split(" ")) } + return args +} + +internal fun JvmCompilationTask.preProcessingSteps( + context: CompilationTaskContext, + pluginArgsEncoder: KotlinCompilerPluginArgsEncoder, + compiler: KotlinToolchain.KotlincInvoker +): JvmCompilationTask { + ensureDirectories( + directories.temp, + directories.generatedSources, + directories.generatedClasses + ) + val taskWithAdditionalSources = context.execute("expand sources") { expandWithSourceJarSources() } + return context.execute({ + "kapt (${inputs.processorsList.joinToString(", ")})" + }) { taskWithAdditionalSources.runAnnotationProcessors(context, pluginArgsEncoder, compiler) } +} + +internal fun JvmCompilationTask.produceSourceJar() { + Paths.get(outputs.srcjar).also { sourceJarPath -> + Files.createFile(sourceJarPath) + SourceJarCreator( + sourceJarPath + ).also { creator -> + // This check asserts that source jars were unpacked if present. + check( + inputs.sourceJarsList.isEmpty() || + Files.exists(Paths.get(directories.temp).resolve("_srcjars")) + ) + listOf( + // Any (input) source jars should already have been expanded so do not add them here. + inputs.javaSourcesList.stream(), + inputs.kotlinSourcesList.stream() + ).stream() + .flatMap { it.map { p -> Paths.get(p) } } + .also { creator.addSources(it) } + creator.execute() + } + } +} + +internal fun JvmCompilationTask.runAnnotationProcessor( + context: CompilationTaskContext, + pluginArgsEncoder: KotlinCompilerPluginArgsEncoder, + compiler: KotlinToolchain.KotlincInvoker, + printOnSuccess: Boolean = true +): List { + check(inputs.processorsList.isNotEmpty()) { "method called without annotation processors" } + return getCommonArgs().let { args -> + args.addAll(pluginArgsEncoder.encode(context, this)) + args.addAll(inputs.kotlinSourcesList) + args.addAll(inputs.javaSourcesList) + context.executeCompilerTask(args, compiler::compile, printOnSuccess = printOnSuccess) + } +} + +internal fun JvmCompilationTask.runAnnotationProcessors( + context: CompilationTaskContext, + pluginArgsEncoder: KotlinCompilerPluginArgsEncoder, + compiler: KotlinToolchain.KotlincInvoker +): JvmCompilationTask = + if (inputs.processorsList.isEmpty()) { + this + } else { + runAnnotationProcessor( + context, + pluginArgsEncoder, + compiler, + printOnSuccess = context.whenTracing { false } ?: true).let { outputLines -> + // if tracing is enabled the output should be formatted in a special way, if we aren't tracing then any + // compiler output would make it's way to the console as is. + context.whenTracing { + printLines("kapt output", outputLines) + } + expandWithGeneratedSources() + } + } + +/** + * Produce the primary output jar. + */ +internal fun JvmCompilationTask.createOutputJar() = + JarCreator( + path = Paths.get(outputs.jar), + normalize = true, + verbose = false + ).also { + it.addDirectory(Paths.get(directories.classes)) + it.addDirectory(Paths.get(directories.generatedClasses)) + it.setJarOwner(info.label, info.bazelRuleKind) + it.execute() + } + +internal fun JvmCompilationTask.compileAll( + context: CompilationTaskContext, + compiler: KotlinToolchain.KotlincInvoker, + javaCompiler: JavaCompiler +) { + ensureDirectories( + directories.classes + ) + var kotlinError: CompilationStatusException? = null + var result: List? = null + context.execute("kotlinc") { + result = try { + compileKotlin(context, compiler, printOnFail = false) + } catch (ex: CompilationStatusException) { + kotlinError = ex + ex.lines + } + } + try { + context.execute("javac") { javaCompiler.compile(context, this) } + } finally { + checkNotNull(result).also(context::printCompilerOutput) + kotlinError?.also { throw it } + } +} + +/** + * Compiles Kotlin sources to classes. Does not compile Java sources. + */ +internal fun JvmCompilationTask.compileKotlin( + context: CompilationTaskContext, + compiler: KotlinToolchain.KotlincInvoker, + printOnFail: Boolean = true +) = + getCommonArgs().let { args -> + args.addAll(inputs.javaSourcesList) + args.addAll(inputs.kotlinSourcesList) + context.executeCompilerTask(args, compiler::compile, printOnFail = printOnFail) + } + +/** + * If any srcjars were provided expand the jars sources and create a new [JvmCompilationTask] with the + * Java and Kotlin sources merged in. + */ +internal fun JvmCompilationTask.expandWithSourceJarSources(): JvmCompilationTask = + if (inputs.sourceJarsList.isEmpty()) + this + else expandWithSources( + SourceJarExtractor( + destDir = Paths.get(directories.temp).resolve("_srcjars"), + fileMatcher = IS_JVM_SOURCE_FILE + ).also { + it.jarFiles.addAll(inputs.sourceJarsList.map { p -> Paths.get(p) }) + it.execute() + }.sourcesList.iterator() + ) + +/** + * Create a new [JvmCompilationTask] with sources found in the generatedSources directory. This should be run after + * annotation processors have been run. + */ +internal fun JvmCompilationTask.expandWithGeneratedSources(): JvmCompilationTask = + expandWithSources( + File(directories.generatedSources).walkTopDown() + .filter { it.isFile } + .map { it.path } + .iterator() + ) + +internal fun JvmCompilationTask.expandWithSources(sources: Iterator): JvmCompilationTask = + updateBuilder { builder -> + sources.partitionJvmSources( + { builder.inputsBuilder.addKotlinSources(it) }, + { builder.inputsBuilder.addJavaSources(it) }) + } + +internal fun JvmCompilationTask.updateBuilder( + block: (JvmCompilationTask.Builder) -> Unit +): JvmCompilationTask = + toBuilder().let { + block(it) + it.build() + } diff --git a/src/main/kotlin/io/bazel/kotlin/builder/toolchain/BUILD.bazel b/src/main/kotlin/io/bazel/kotlin/builder/toolchain/BUILD.bazel new file mode 100644 index 000000000..b9c66dc22 --- /dev/null +++ b/src/main/kotlin/io/bazel/kotlin/builder/toolchain/BUILD.bazel @@ -0,0 +1,30 @@ +# Copyright 2018 The Bazel Authors. 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 + +load("//src/main/kotlin:bootstrap.bzl", "kt_bootstrap_library") + +kt_bootstrap_library( + name = "toolchain", + srcs = glob([ + "*.kt", + ]), + visibility = ["//src:__subpackages__"], + deps = [ + "//src/main/protobuf:kotlin_model_java_proto", + "@com_github_jetbrains_kotlin//:kotlin-preloader", + "@kotlin_rules_maven//:com_google_protobuf_protobuf_java", + "@kotlin_rules_maven//:com_google_protobuf_protobuf_java_util", + "@kotlin_rules_maven//:javax_inject_javax_inject", + "//src/main/kotlin/io/bazel/kotlin/builder/utils:utils", + ], +) diff --git a/src/main/kotlin/io/bazel/kotlin/builder/utils/CompilationTaskContext.kt b/src/main/kotlin/io/bazel/kotlin/builder/toolchain/CompilationTaskContext.kt similarity index 95% rename from src/main/kotlin/io/bazel/kotlin/builder/utils/CompilationTaskContext.kt rename to src/main/kotlin/io/bazel/kotlin/builder/toolchain/CompilationTaskContext.kt index 9d02c202f..42c04a6b1 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/utils/CompilationTaskContext.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/toolchain/CompilationTaskContext.kt @@ -13,11 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.bazel.kotlin.builder.utils +package io.bazel.kotlin.builder.toolchain import com.google.protobuf.MessageOrBuilder import com.google.protobuf.TextFormat -import io.bazel.kotlin.builder.toolchain.CompilationStatusException import io.bazel.kotlin.model.CompilationTaskInfo import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream @@ -32,8 +31,7 @@ class CompilationTaskContext(val info: CompilationTaskInfo, private val out: Pri ).toAbsolutePath().toString() + File.separator private var timings: MutableList? private var level = -1 - @PublishedApi - internal val isTracing: Boolean + private val isTracing: Boolean init { val debugging = info.debugList.toSet() @@ -69,7 +67,7 @@ class CompilationTaskContext(val info: CompilationTaskInfo, private val out: Pri out.println() } - inline fun whenTracing(block: CompilationTaskContext.() -> T): T? { + fun whenTracing(block: CompilationTaskContext.() -> T): T? { return if (isTracing) { block() } else null @@ -105,7 +103,7 @@ class CompilationTaskContext(val info: CompilationTaskInfo, private val out: Pri * for logging it by catching the [CompilationStatusException] exception. * @param compile the compilation method. */ - inline fun executeCompilerTask( + fun executeCompilerTask( args: List, compile: (Array, PrintStream) -> Int, printOnFail: Boolean = true, diff --git a/src/main/kotlin/io/bazel/kotlin/builder/utils/KotlinCompilerPluginArgsEncoder.kt b/src/main/kotlin/io/bazel/kotlin/builder/toolchain/KotlinCompilerPluginArgsEncoder.kt similarity index 98% rename from src/main/kotlin/io/bazel/kotlin/builder/utils/KotlinCompilerPluginArgsEncoder.kt rename to src/main/kotlin/io/bazel/kotlin/builder/toolchain/KotlinCompilerPluginArgsEncoder.kt index 93eba5998..f141159bc 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/utils/KotlinCompilerPluginArgsEncoder.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/toolchain/KotlinCompilerPluginArgsEncoder.kt @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.bazel.kotlin.builder.utils +package io.bazel.kotlin.builder.toolchain import io.bazel.kotlin.model.JvmCompilationTask import java.io.ByteArrayOutputStream import java.io.ObjectOutputStream -import java.util.* +import java.util.Base64 // TODO(hs) move the kapt specific stuff to the JVM package. class KotlinCompilerPluginArgsEncoder( diff --git a/src/main/kotlin/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt b/src/main/kotlin/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt index 5fbf9e736..d76f48e0b 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt @@ -29,112 +29,116 @@ import javax.inject.Inject import javax.inject.Singleton class KotlinToolchain private constructor( - val kotlinHome: Path, - val classLoader: ClassLoader, - val kotlinStandardLibraries: List = listOf( - "kotlin-stdlib.jar", - "kotlin-stdlib-jdk7.jar", - "kotlin-stdlib-jdk8.jar" - ), - val kapt3Plugin: KotlinToolchain.CompilerPlugin = KotlinToolchain.CompilerPlugin( - kotlinHome.resolveVerified("lib", "kotlin-annotation-processing.jar").absolutePath, - "org.jetbrains.kotlin.kapt3" - ) + val kotlinHome: Path, + val classLoader: ClassLoader, + val kotlinStandardLibraries: List = listOf( + "kotlin-stdlib.jar", + "kotlin-stdlib-jdk7.jar", + "kotlin-stdlib-jdk8.jar" + ), + val kapt3Plugin: KotlinToolchain.CompilerPlugin = KotlinToolchain.CompilerPlugin( + kotlinHome.resolveVerified("lib", "kotlin-annotation-processing.jar").absolutePath, + "org.jetbrains.kotlin.kapt3" + ) ) { - companion object { - internal val NO_ARGS = arrayOf() - - private val isJdk9OrNewer = !System.getProperty("java.version").startsWith("1.") - - private fun createClassLoader(javaHome: Path, baseJars: List): ClassLoader = - ClassPreloadingUtils.preloadClasses( - mutableListOf().also { - it += baseJars - if (!isJdk9OrNewer) { - it += javaHome.resolveVerified("lib", "tools.jar") - } - }, - Preloader.DEFAULT_CLASS_NUMBER_ESTIMATE, - ClassLoader.getSystemClassLoader(), - null - ) - - @JvmStatic - fun createToolchain(): KotlinToolchain { - val javaHome = Paths.get(System.getProperty("java.home")).let { path -> - path.takeIf { !it.endsWith(Paths.get("jre")) } ?: path.parent - } - val kotlinCompilerJar = BazelRunFiles.resolveVerified( - "external", "com_github_jetbrains_kotlin", "lib", "kotlin-compiler.jar") - return KotlinToolchain( - kotlinCompilerJar.toPath().parent.parent, - createClassLoader( - javaHome, - listOf( - kotlinCompilerJar, - BazelRunFiles.resolveVerified( - "io_bazel_rules_kotlin", "src", "main", "kotlin", "compiler_lib.jar") - ) - ) - ) - } + companion object { + internal val NO_ARGS = arrayOf() + + private val isJdk9OrNewer = !System.getProperty("java.version").startsWith("1.") + + private fun createClassLoader(javaHome: Path, baseJars: List): ClassLoader = + ClassPreloadingUtils.preloadClasses( + mutableListOf().also { + it += baseJars + if (!isJdk9OrNewer) { + it += javaHome.resolveVerified("lib", "tools.jar") + } + }, + Preloader.DEFAULT_CLASS_NUMBER_ESTIMATE, + ClassLoader.getSystemClassLoader(), + null + ) + + @JvmStatic + fun createToolchain(): KotlinToolchain { + val javaHome = Paths.get(System.getProperty("java.home")).let { path -> + path.takeIf { !it.endsWith(Paths.get("jre")) } ?: path.parent + } + val kotlinCompilerJar = BazelRunFiles.resolveVerified( + "external", "com_github_jetbrains_kotlin", "lib", "kotlin-compiler.jar") + return KotlinToolchain( + kotlinCompilerJar.toPath().parent.parent, + createClassLoader( + javaHome, + listOf( + kotlinCompilerJar, + BazelRunFiles.resolveVerified( + "io_bazel_rules_kotlin", + "src", "main", "kotlin", "io", "bazel", "kotlin", "compiler", + "compiler.jar") + ) + ) + ) } - - data class CompilerPlugin(val jarPath: String, val id: String) - - @Singleton - class JavacInvoker @Inject constructor(toolchain: KotlinToolchain) { - private val c = toolchain.classLoader.loadClass("com.sun.tools.javac.Main") - private val m = c.getMethod("compile", Array::class.java) - private val mPw = c.getMethod("compile", Array::class.java, PrintWriter::class.java) - fun compile(args: Array) = m.invoke(c, args) as Int - fun compile(args: Array, out: PrintWriter) = mPw.invoke(c, args, out) as Int - } - - @Singleton - class JDepsInvoker @Inject constructor(toolchain: KotlinToolchain) { - private val clazz = toolchain.classLoader.loadClass("com.sun.tools.jdeps.Main") - private val method = clazz.getMethod("run", Array::class.java, PrintWriter::class.java) - fun run(args: Array, out: PrintWriter): Int = method.invoke(clazz, args, out) as Int + } + + data class CompilerPlugin(val jarPath: String, val id: String) + + @Singleton + class JavacInvoker @Inject constructor(toolchain: KotlinToolchain) { + private val c = toolchain.classLoader.loadClass("com.sun.tools.javac.Main") + private val m = c.getMethod("compile", Array::class.java) + private val mPw = c.getMethod("compile", Array::class.java, PrintWriter::class.java) + fun compile(args: Array) = m.invoke(c, args) as Int + fun compile(args: Array, out: PrintWriter) = mPw.invoke(c, args, out) as Int + } + + @Singleton + class JDepsInvoker @Inject constructor(toolchain: KotlinToolchain) { + private val clazz = toolchain.classLoader.loadClass("com.sun.tools.jdeps.Main") + private val method = clazz.getMethod("run", Array::class.java, PrintWriter::class.java) + fun run(args: Array, out: PrintWriter): Int = method.invoke(clazz, args, out) as Int + } + + open class KotlinCliToolInvoker internal constructor( + toolchain: KotlinToolchain, + clazz: String + ) { + private val compiler: Any + private val execMethod: Method + private val getCodeMethod: Method + + init { + val compilerClass = toolchain.classLoader.loadClass(clazz) + val exitCodeClass = + toolchain.classLoader.loadClass("org.jetbrains.kotlin.cli.common.ExitCode") + + compiler = compilerClass.getConstructor().newInstance() + execMethod = + compilerClass.getMethod("exec", PrintStream::class.java, Array::class.java) + getCodeMethod = exitCodeClass.getMethod("getCode") } - open class KotlinCliToolInvoker internal constructor( - toolchain: KotlinToolchain, - clazz: String - ) { - private val compiler: Any - private val execMethod: Method - private val getCodeMethod: Method - - init { - val compilerClass = toolchain.classLoader.loadClass(clazz) - val exitCodeClass = toolchain.classLoader.loadClass("org.jetbrains.kotlin.cli.common.ExitCode") - - compiler = compilerClass.getConstructor().newInstance() - execMethod = compilerClass.getMethod("exec", PrintStream::class.java, Array::class.java) - getCodeMethod = exitCodeClass.getMethod("getCode") - } - - // Kotlin error codes: - // 1 is a standard compilation error - // 2 is an internal error - // 3 is the script execution error - fun compile(args: Array, out: PrintStream): Int { - val exitCodeInstance = execMethod.invoke(compiler, out, args) - return getCodeMethod.invoke(exitCodeInstance, *NO_ARGS) as Int - } + // Kotlin error codes: + // 1 is a standard compilation error + // 2 is an internal error + // 3 is the script execution error + fun compile(args: Array, out: PrintStream): Int { + val exitCodeInstance = execMethod.invoke(compiler, out, args) + return getCodeMethod.invoke(exitCodeInstance, *NO_ARGS) as Int } + } - @Singleton - class KotlincInvoker @Inject constructor( - toolchain: KotlinToolchain - ) : KotlinCliToolInvoker(toolchain, "io.bazel.kotlin.compiler.BazelK2JVMCompiler") + @Singleton + class KotlincInvoker @Inject constructor( + toolchain: KotlinToolchain + ) : KotlinCliToolInvoker(toolchain, "io.bazel.kotlin.compiler.BazelK2JVMCompiler") - @Singleton - class K2JSCompilerInvoker @Inject constructor( - toolchain: KotlinToolchain - ) : KotlinCliToolInvoker(toolchain, "org.jetbrains.kotlin.cli.js.K2JSCompiler") + @Singleton + class K2JSCompilerInvoker @Inject constructor( + toolchain: KotlinToolchain + ) : KotlinCliToolInvoker(toolchain, "org.jetbrains.kotlin.cli.js.K2JSCompiler") } diff --git a/src/main/kotlin/io/bazel/kotlin/builder/utils/BUILD.bazel b/src/main/kotlin/io/bazel/kotlin/builder/utils/BUILD.bazel new file mode 100644 index 000000000..f82e208c3 --- /dev/null +++ b/src/main/kotlin/io/bazel/kotlin/builder/utils/BUILD.bazel @@ -0,0 +1,31 @@ +# Copyright 2020 The Bazel Authors. 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("@rules_java//java:defs.bzl", "java_library") +load("//src/main/kotlin:bootstrap.bzl", "kt_bootstrap_library") + +kt_bootstrap_library( + name = "utils", + visibility = ["//src:__subpackages__",], + srcs = glob([ + "*.kt", + "**/*.kt", + ]), + deps = [ + "//src/main/protobuf:deps_java_proto", + "//src/main/protobuf:kotlin_model_java_proto", + "//src/main/protobuf:worker_protocol_java_proto", + "@kotlin_rules_maven//:com_google_protobuf_protobuf_java", + "@kotlin_rules_maven//:com_google_protobuf_protobuf_java_util", + ], +) diff --git a/src/main/kotlin/io/bazel/kotlin/compiler/BUILD.bazel b/src/main/kotlin/io/bazel/kotlin/compiler/BUILD.bazel new file mode 100644 index 000000000..d997f18ef --- /dev/null +++ b/src/main/kotlin/io/bazel/kotlin/compiler/BUILD.bazel @@ -0,0 +1,27 @@ +# Copyright 2020 The Bazel Authors. 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("//src/main/kotlin:bootstrap.bzl", "kt_bootstrap_library") + +# The compiler library, this is co-located in the kotlin compiler classloader. +kt_bootstrap_library( + name = "compiler", + srcs = glob(["*.kt"]), + visibility = ["//src:__subpackages__"], + neverlink_deps = [ + "@com_github_jetbrains_kotlin//:kotlin-compiler", + "@com_github_jetbrains_kotlin//:kotlin-annotation-processing", + "@com_github_jetbrains_kotlin//:kotlin-script-runtime", + ], +) diff --git a/src/test/kotlin/io/bazel/kotlin/builder/BUILD b/src/test/kotlin/io/bazel/kotlin/builder/BUILD index 25c745f22..9c366abfb 100644 --- a/src/test/kotlin/io/bazel/kotlin/builder/BUILD +++ b/src/test/kotlin/io/bazel/kotlin/builder/BUILD @@ -11,13 +11,15 @@ # 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(default_visibility = ["//visibility:private"]) +package(default_visibility = ["//src:__subpackages__"]) load("@rules_java//java:defs.bzl", "java_library") load("//src/test/kotlin/io/bazel/kotlin:defs.bzl", "kt_rules_test") _COMMON_DEPS = [ "//src/main/kotlin/io/bazel/kotlin/builder", + "//src/main/kotlin/io/bazel/kotlin/builder/toolchain", + "//src/main/kotlin/io/bazel/kotlin/builder/utils:utils", "//src/main/protobuf:kotlin_model_java_proto", "//src/main/protobuf:deps_java_proto", "@kotlin_rules_maven//:com_google_truth_truth", @@ -37,7 +39,7 @@ java_library( "KotlinJvmTestBuilder.java", ], data = [ - "//src/main/kotlin:compiler_lib", + "//src/main/kotlin/io/bazel/kotlin/compiler", "@com_github_jetbrains_kotlin//:home", ], exports = _COMMON_DEPS + [ @@ -52,60 +54,11 @@ java_library( ], ) -kt_rules_test( - name = "SourceJarCreatorTest", - srcs = ["utils/jars/SourceJarCreatorTest.java"], -) - -kt_rules_test( - name = "JdepsParserTest", - srcs = ["tasks/jvm/JdepsParserTest.java"], -) - -kt_rules_test( - name = "KotlinBuilderJvmBasicTest", - srcs = ["tasks/jvm/KotlinBuilderJvmBasicTest.java"], -) - -kt_rules_test( - name = "KotlinJvmTaskExecutorTest", - srcs = ["tasks/jvm/KotlinJvmTaskExecutorTest.kt"], - deps = ["@com_github_jetbrains_kotlin//:kotlin-test"], -) - -# TODO(bazelbuild/rules_kotlin/issues/275): Remove full jar reference when the kt_rules_test handles jvm_import data better. -_MAVEN_CENTRAL_PREFIX = "@kotlin_rules_maven//:v1/https/maven-central.storage.googleapis.com/repos/central/data" -_AUTO_VALUE_PREFIX = "%s/com/google/auto/value" % _MAVEN_CENTRAL_PREFIX -_AUTO_VALUE_JAR = _AUTO_VALUE_PREFIX+ "/auto-value/1.6.5/auto-value-1.6.5.jar" -_AUTO_VALUE_ANNOTATIONS_JAR = _AUTO_VALUE_PREFIX+ "/auto-value-annotations/1.6.5/auto-value-annotations-1.6.5.jar" - -kt_rules_test( - name = "KotlinBuilderJvmKaptTest", - srcs = ["tasks/jvm/KotlinBuilderJvmKaptTest.java"], - data = [ - _AUTO_VALUE_JAR, - _AUTO_VALUE_ANNOTATIONS_JAR, - ], - jvm_flags = [ - "-Dauto_value=$(location %s)" % _AUTO_VALUE_JAR, - "-Dauto_value_annotations=$(location %s)" % _AUTO_VALUE_ANNOTATIONS_JAR, - ], -) - -kt_rules_test( - name = "KotlinBuilderJsTest", - srcs = ["tasks/js/KotlinBuilderJsTest.java"], -) - test_suite( name = "builder_tests", tests = [ - ":JdepsParserTest", - ":KotlinBuilderJsTest", - ":KotlinBuilderJvmBasicTest", - ":KotlinBuilderJvmKaptTest", - ":KotlinJvmTaskExecutorTest", - ":SourceJarCreatorTest", + "//src/test/kotlin/io/bazel/kotlin/builder/utils", + "//src/test/kotlin/io/bazel/kotlin/builder/tasks", ], visibility = ["//visibility:public"], ) diff --git a/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java b/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java index 3cab60cec..ab0e5e03e 100644 --- a/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java +++ b/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java @@ -16,7 +16,7 @@ package io.bazel.kotlin.builder; import io.bazel.kotlin.builder.toolchain.CompilationStatusException; -import io.bazel.kotlin.builder.utils.CompilationTaskContext; +import io.bazel.kotlin.builder.toolchain.CompilationTaskContext; import io.bazel.kotlin.model.*; import java.io.*; diff --git a/src/test/kotlin/io/bazel/kotlin/builder/tasks/BUILD.bazel b/src/test/kotlin/io/bazel/kotlin/builder/tasks/BUILD.bazel new file mode 100644 index 000000000..7da6e958b --- /dev/null +++ b/src/test/kotlin/io/bazel/kotlin/builder/tasks/BUILD.bazel @@ -0,0 +1,56 @@ +# Copyright 2020 The Bazel Authors. 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("//src/test/kotlin/io/bazel/kotlin:defs.bzl", "kt_rules_test") + +kt_rules_test( + name = "JdepsParserTest", + srcs = ["jvm/JdepsParserTest.java"], + deps = [ + "//src/main/kotlin/io/bazel/kotlin/builder/tasks", + ] +) + +kt_rules_test( + name = "KotlinBuilderJvmBasicTest", + srcs = ["jvm/KotlinBuilderJvmBasicTest.java"], +) + +# TODO(bazelbuild/rules_kotlin/issues/275): Remove full jar reference when the kt_rules_test handles jvm_import data better. +_MAVEN_CENTRAL_PREFIX = "@kotlin_rules_maven//:v1/https/maven-central.storage.googleapis.com/repos/central/data" +_AUTO_VALUE_PREFIX = "%s/com/google/auto/value" % _MAVEN_CENTRAL_PREFIX +_AUTO_VALUE_JAR = _AUTO_VALUE_PREFIX+ "/auto-value/1.6.5/auto-value-1.6.5.jar" +_AUTO_VALUE_ANNOTATIONS_JAR = _AUTO_VALUE_PREFIX+ "/auto-value-annotations/1.6.5/auto-value-annotations-1.6.5.jar" + +kt_rules_test( + name = "KotlinBuilderJvmKaptTest", + srcs = ["jvm/KotlinBuilderJvmKaptTest.java"], + data = [ + _AUTO_VALUE_JAR, + _AUTO_VALUE_ANNOTATIONS_JAR, + ], + jvm_flags = [ + "-Dauto_value=$(location %s)" % _AUTO_VALUE_JAR, + "-Dauto_value_annotations=$(location %s)" % _AUTO_VALUE_ANNOTATIONS_JAR, + ], +) + +kt_rules_test( + name = "KotlinBuilderJsTest", + srcs = ["js/KotlinBuilderJsTest.java"], +) + +test_suite( + name = "tasks", +) \ No newline at end of file diff --git a/src/test/kotlin/io/bazel/kotlin/builder/utils/BUILD.bazel b/src/test/kotlin/io/bazel/kotlin/builder/utils/BUILD.bazel new file mode 100644 index 000000000..7390cabed --- /dev/null +++ b/src/test/kotlin/io/bazel/kotlin/builder/utils/BUILD.bazel @@ -0,0 +1,25 @@ +# Copyright 2020 The Bazel Authors. 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(default_visibility = ["//src:__subpackages__"]) + +load("//src/test/kotlin/io/bazel/kotlin:defs.bzl", "kt_rules_test") + +kt_rules_test( + name = "SourceJarCreatorTest", + srcs = ["jars/SourceJarCreatorTest.java"], +) + +test_suite( + name = "utils", +)