diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index 7c4f0dc14..bd17f338b 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -156,16 +156,16 @@ tasks: - test build_targets: - //... - examples-nodejs: - name: Example - Node - platform: ubuntu1804 - working_directory: examples/node - include_json_profile: - - build - - test - build_targets: - - //coroutines-helloworld/... - - //express/... +# examples-nodejs: +# name: Example - Node +# platform: ubuntu1804 +# working_directory: examples/node +# include_json_profile: +# - build +# - test +# build_targets: +# - //coroutines-helloworld/... +# - //express/... example-jetpack-compose: name: "Example - Jetpack Compose" platform: ubuntu1804 diff --git a/README.md b/README.md index 635ebf21f..15f7ab913 100644 --- a/README.md +++ b/README.md @@ -97,9 +97,9 @@ load("@rules_kotlin//kotlin:core.bzl", "define_kt_toolchain") define_kt_toolchain( name = "kotlin_toolchain", - api_version = KOTLIN_LANGUAGE_LEVEL, # "1.1", "1.2", "1.3", "1.4", "1.5" "1.6", or "1.7" + api_version = KOTLIN_LANGUAGE_LEVEL, # "1.1", "1.2", "1.3", "1.4", "1.5" "1.6", "1.7", "1.8", or "1.9" jvm_target = JAVA_LANGUAGE_LEVEL, # "1.6", "1.8", "9", "10", "11", "12", "13", "15", "16", or "17" - language_version = KOTLIN_LANGUAGE_LEVEL, # "1.1", "1.2", "1.3", "1.4", "1.5" "1.6", or "1.7" + language_version = KOTLIN_LANGUAGE_LEVEL, # "1.1", "1.2", "1.3", "1.4", "1.5" "1.6", "1.7", "1.8", or "1.9" ) ``` diff --git a/examples/node/express/BUILD b/examples/node/express/BUILD index 6b7edbe29..6ce59cf6c 100644 --- a/examples/node/express/BUILD +++ b/examples/node/express/BUILD @@ -30,6 +30,10 @@ kt_js_library( kt_js_library( name = "app", srcs = [":App.kt"], + tags = [ + "timings", + "trace", + ], deps = [ ":acme-routes", "//:kotlinx-coroutines-core", diff --git a/examples/node/express/auth/BUILD b/examples/node/express/auth/BUILD index 4c465e3f4..c69c124f1 100644 --- a/examples/node/express/auth/BUILD +++ b/examples/node/express/auth/BUILD @@ -16,5 +16,6 @@ load("@rules_kotlin//kotlin:js.bzl", "kt_js_library") kt_js_library( name = "acme-auth", srcs = ["Auth.kt"], + tags = ["trace"], visibility = ["//visibility:public"], ) diff --git a/kotlin/internal/js/impl.bzl b/kotlin/internal/js/impl.bzl index 14d43d461..65a815293 100644 --- a/kotlin/internal/js/impl.bzl +++ b/kotlin/internal/js/impl.bzl @@ -34,14 +34,6 @@ load( def kt_js_library_impl(ctx): toolchain = ctx.toolchains[_TOOLCHAIN_TYPE] - # meta.js is merged in with the js in the builder. It is declared as it's created at the package level and not in - # some anonymous directory. - out_meta = ctx.actions.declare_file(ctx.attr.name + ".meta.js") - - # The Kotlin compiler and intellij infrastructure uses jars and bytecode. The out dir contains bytecode generated by - # the kotlin compiler. In addition to the js and js.map file a jar is also produced. - out_dir = ctx.actions.declare_directory(ctx.label.name) - libraries = depset([d[_KtJsInfo].jar for d in ctx.attr.deps]) args = _utils.init_args( @@ -54,8 +46,8 @@ def kt_js_library_impl(ctx): "--kotlin_js_passthrough_flags", [ "-source-map", - "-meta-info", - "-no-stdlib", # TODO remove this once the stdlib is not conveyed to node via the deps attribute. + "-Xir-produce-klib-dir", + "-no-stdlib", "-module-kind", ctx.attr.module_kind, "-target", @@ -64,7 +56,6 @@ def kt_js_library_impl(ctx): ) args.add("--output", ctx.outputs.js) - args.add("--kotlin_js_dir", out_dir.path) args.add("--kotlin_output_js_jar", ctx.outputs.jar) args.add("--kotlin_output_srcjar", ctx.outputs.srcjar) args.add("--strict_kotlin_deps", "off") @@ -83,8 +74,6 @@ def kt_js_library_impl(ctx): ctx.outputs.js_map, ctx.outputs.jar, ctx.outputs.srcjar, - out_meta, - out_dir, ], executable = toolchain.kotlinbuilder.files_to_run.executable, execution_requirements = {"supports-workers": "1"}, diff --git a/kotlin/internal/toolchains.bzl b/kotlin/internal/toolchains.bzl index 849957128..b1f00510b 100644 --- a/kotlin/internal/toolchains.bzl +++ b/kotlin/internal/toolchains.bzl @@ -134,6 +134,7 @@ _kt_toolchain = rule( "1.6", "1.7", "1.8", + "1.9", ], ), "api_version": attr.string( @@ -148,6 +149,7 @@ _kt_toolchain = rule( "1.6", "1.7", "1.8", + "1.9", ], ), "debug": attr.string_list( 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 2b09e2742..122cab678 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 @@ -6,16 +6,17 @@ import io.bazel.kotlin.builder.toolchain.KotlinToolchain 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.model.JsCompilationTask -import java.io.FileOutputStream import java.nio.file.FileSystem import java.nio.file.FileSystems import java.nio.file.Files import java.nio.file.Path -import java.nio.file.Paths +import java.util.stream.Collectors import javax.inject.Inject import javax.inject.Singleton +import kotlin.io.path.absolute +import kotlin.io.path.absolutePathString +import kotlin.io.path.nameWithoutExtension @Singleton class Kotlin2JsTaskExecutor @Inject constructor( @@ -28,64 +29,64 @@ class Kotlin2JsTaskExecutor @Inject constructor( context: CompilationTaskContext, task: JsCompilationTask, ) { - task.compile(context) - - val jsPath = fileSystem.getPath(task.outputs.js) - val jsMetaFile = jsPath.resolveTwinVerified(".meta.js") - val jsDirectory = Files.createDirectories( - fileSystem.getPath(task.directories.temp) - .resolve(jsPath.toFile().nameWithoutExtension), - ) - task.createJar( - jsDirectory, - listOf(jsPath, jsPath.resolveTwinVerified(".js.map"), jsMetaFile), - ) - // this mutates the jsPath file , so do it after creating the jar. - appendMetaToPrimary(jsPath, jsMetaFile) + val outputDirectory = task.compile(context) + task.createJar(outputDirectory) task.createSourceJar() } - private fun JsCompilationTask.compile(context: CompilationTaskContext) { - val args = mutableListOf().also { - it.addAll(passThroughFlagsList) - it.addAll("-libraries", inputs.librariesList.joinToString(":")) - it.addAll("-output", outputs.js) - it.addAll("-Xuse-deprecated-legacy-compiler") - it.addAll(inputs.kotlinSourcesList) + private fun JsCompilationTask.compile(context: CompilationTaskContext): Path { + val jsOut = fileSystem.getPath(outputs.js) + val outputDirectory = jsOut.parent + val baseName = jsOut.fileName.nameWithoutExtension + val mapOut = outputDirectory.resolve("$baseName.js.map") + val workingDirectory = fileSystem.getPath(directories.temp) + + val execRoot = fileSystem.getPath(".").absolute() + + val args = mutableListOf().apply { + addAll(passThroughFlagsList) + add("-Xdisable-default-scripting-plugin") + add("-Xir-produce-js") + add("-progressive") + add("-Xoptimize-generated-js=false") + addAll( + "-libraries", + inputs.librariesList.map { execRoot.resolve(it).absolutePathString() }.joinToString(":"), + ) + addAll("-ir-output-name", baseName) + addAll("-ir-output-dir", workingDirectory.toString()) + addAll("-Xir-module-name=${info.moduleName}") + addAll(inputs.kotlinSourcesList.map { execRoot.resolve(it).absolutePathString() }) } + context.whenTracing { printLines("js compile args", args) } context.executeCompilerTask(args, invoker::compile) + context.whenTracing { + printLines( + "outputs", + Files.walk(outputDirectory).map { p -> p.toString() }.collect(Collectors.toList()), + ) + } + Files.copy(workingDirectory.resolve(jsOut.fileName), jsOut) + Files.copy(workingDirectory.resolve(mapOut.fileName), mapOut) + + return workingDirectory } private fun JsCompilationTask.createSourceJar() { try { - SourceJarCreator(Paths.get(outputs.srcjar), false).also { creator -> - creator.addSources(inputs.kotlinSourcesList.map { Paths.get(it) }.stream()) + SourceJarCreator(fileSystem.getPath(outputs.srcjar), false).also { creator -> + creator.addSources(inputs.kotlinSourcesList.map { fileSystem.getPath(it) }.stream()) }.execute() } catch (ex: Throwable) { throw CompilationException("could not create source jar", ex) } } - /** - * Append the meta file to the JS file. This is an accepted pattern, and it allows us to not have to export the - * meta.js file with the js. - */ - private fun appendMetaToPrimary(jsPath: Path, jsMetaFile: Path) { + private fun JsCompilationTask.createJar(jsDirectoryPath: Path) { try { - FileOutputStream(jsPath.toFile(), true).use { Files.copy(jsMetaFile, it) } - } catch (ex: Throwable) { - throw CompilationException("could not normalize js file", ex) - } - } - - private fun JsCompilationTask.createJar(jsDirectoryPath: Path, rootEntries: List) { - try { - val outputJarPath = Paths.get(outputs.jar) - - JarCreator(outputJarPath).also { creator -> + JarCreator(fileSystem.getPath(outputs.jar)).use { creator -> creator.addDirectory(jsDirectoryPath) - creator.addRootEntries(rootEntries.map { it.toString() }) creator.execute() } } catch (ex: Throwable) { diff --git a/src/main/kotlin/io/bazel/kotlin/plugin/BUILD.bazel b/src/main/kotlin/io/bazel/kotlin/plugin/BUILD.bazel index e647dc545..146df86d2 100644 --- a/src/main/kotlin/io/bazel/kotlin/plugin/BUILD.bazel +++ b/src/main/kotlin/io/bazel/kotlin/plugin/BUILD.bazel @@ -30,7 +30,7 @@ kt_bootstrap_library( generate_jvm_service( name = "skip-code-gen-services", services = { - "io.bazel.kotlin.plugin.SkipCodeGen": "org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar", + "io.bazel.kotlin.plugin.SkipCodeGen": "org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar", }, ) diff --git a/src/main/kotlin/io/bazel/kotlin/plugin/SkipCodeGen.kt b/src/main/kotlin/io/bazel/kotlin/plugin/SkipCodeGen.kt index f9eea10d1..5254b9ae4 100644 --- a/src/main/kotlin/io/bazel/kotlin/plugin/SkipCodeGen.kt +++ b/src/main/kotlin/io/bazel/kotlin/plugin/SkipCodeGen.kt @@ -17,10 +17,9 @@ package io.bazel.kotlin.plugin import com.google.common.base.Preconditions -import com.intellij.mock.MockProject import com.intellij.openapi.project.Project import org.jetbrains.kotlin.analyzer.AnalysisResult -import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar +import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.container.ComponentProvider import org.jetbrains.kotlin.context.ProjectContext @@ -33,20 +32,17 @@ import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension * SkipCodeGen registers an extension to skip code generation. Must be the last compiler plugin. */ @OptIn(org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi::class) -class SkipCodeGen : ComponentRegistrar { +class SkipCodeGen : CompilerPluginRegistrar() { - companion object { - val COMPILER_PLUGIN_ID = "io.bazel.kotlin.plugin.SkipCodeGen" + override val supportsK2: Boolean + get() = false + + override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) { + AnalysisHandlerExtension.registerExtension(SkipCodeGen) } - override fun registerProjectComponents( - project: MockProject, - configuration: CompilerConfiguration, - ) { - AnalysisHandlerExtension.registerExtension( - project, - SkipCodeGen, - ) + companion object { + val COMPILER_PLUGIN_ID = "io.bazel.kotlin.plugin.SkipCodeGen" } /** @@ -71,7 +67,7 @@ class SkipCodeGen : ComponentRegistrar { module: ModuleDescriptor, bindingTrace: BindingTrace, files: Collection, - ): AnalysisResult? { + ): AnalysisResult { // Ensure this is the last plugin, as it will short circuit any other plugin analysisCompleted // calls. Preconditions.checkState( diff --git a/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/BUILD.bazel b/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/BUILD.bazel index d565ed716..131fa544d 100644 --- a/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/BUILD.bazel +++ b/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/BUILD.bazel @@ -33,7 +33,7 @@ kt_bootstrap_library( generate_jvm_service( name = "jdeps-gen-services", services = { - "io.bazel.kotlin.plugin.jdeps.JdepsGenComponentRegistrar": "org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar", + "io.bazel.kotlin.plugin.jdeps.JdepsGenComponentRegistrar": "org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar", "io.bazel.kotlin.plugin.jdeps.JdepsGenCommandLineProcessor": "org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor", }, ) diff --git a/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/JdepsGenComponentRegistrar.kt b/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/JdepsGenComponentRegistrar.kt index e4d5b5641..35948ebb9 100644 --- a/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/JdepsGenComponentRegistrar.kt +++ b/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/JdepsGenComponentRegistrar.kt @@ -1,22 +1,21 @@ package io.bazel.kotlin.plugin.jdeps -import com.intellij.mock.MockProject -import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar +import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension @OptIn(org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi::class) -class JdepsGenComponentRegistrar : ComponentRegistrar { +class JdepsGenComponentRegistrar : CompilerPluginRegistrar() { - override fun registerProjectComponents( - project: MockProject, - configuration: CompilerConfiguration, - ) { + override val supportsK2: Boolean + get() = false + + override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) { // Capture all types referenced by the compiler for this module and look up the jar from which // they were loaded from - val extension = JdepsGenExtension(project, configuration) - AnalysisHandlerExtension.registerExtension(project, extension) - StorageComponentContainerContributor.registerExtension(project, extension) + val extension = JdepsGenExtension(configuration) + AnalysisHandlerExtension.registerExtension(extension) + StorageComponentContainerContributor.registerExtension(extension) } } diff --git a/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/JdepsGenExtension.kt b/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/JdepsGenExtension.kt index 6c5b68011..09ebc56ad 100644 --- a/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/JdepsGenExtension.kt +++ b/src/main/kotlin/io/bazel/kotlin/plugin/jdeps/JdepsGenExtension.kt @@ -1,7 +1,6 @@ package io.bazel.kotlin.plugin.jdeps import com.google.devtools.build.lib.view.proto.Deps -import com.intellij.mock.MockProject import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement import io.bazel.kotlin.builder.utils.jars.JarOwner @@ -65,7 +64,6 @@ import java.nio.file.Paths * @param configuration the current compilation configuration */ class JdepsGenExtension( - val project: MockProject, val configuration: CompilerConfiguration, ) : AnalysisHandlerExtension, StorageComponentContainerContributor { diff --git a/src/main/starlark/core/repositories/compiler.bzl b/src/main/starlark/core/repositories/compiler.bzl index 98919b5c1..084fead72 100644 --- a/src/main/starlark/core/repositories/compiler.bzl +++ b/src/main/starlark/core/repositories/compiler.bzl @@ -41,6 +41,7 @@ _CAPABILITIES_TEMPLATES = { "1.6": "//src/main/starlark/core/repositories/kotlin:capabilities_1.6.bzl.com_github_jetbrains_kotlin.bazel", "1.7": "//src/main/starlark/core/repositories/kotlin:capabilities_1.7.bzl.com_github_jetbrains_kotlin.bazel", "1.8": "//src/main/starlark/core/repositories/kotlin:capabilities_1.8.bzl.com_github_jetbrains_kotlin.bazel", + "1.9": "//src/main/starlark/core/repositories/kotlin:capabilities_1.9.bzl.com_github_jetbrains_kotlin.bazel", } kotlin_compiler_repository = repository_rule( diff --git a/src/main/starlark/core/repositories/kotlin/capabilities_1.9.bzl.com_github_jetbrains_kotlin.bazel b/src/main/starlark/core/repositories/kotlin/capabilities_1.9.bzl.com_github_jetbrains_kotlin.bazel new file mode 100644 index 000000000..47a48bcc3 --- /dev/null +++ b/src/main/starlark/core/repositories/kotlin/capabilities_1.9.bzl.com_github_jetbrains_kotlin.bazel @@ -0,0 +1,140 @@ +# Copyright 2023 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. +KOTLIN_OPTS = [ + "-Werror", + "-Xabi-stability", + "-Xadd-modules", + "-Xallow-any-scripts-in-source-roots", + "-Xallow-kotlin-package", + "-Xallow-no-source-files", + "-Xallow-result-return-type", + "-Xallow-unstable-dependencies", + "-Xassertions", + "-Xbackend-threads", + "-Xbuiltins-from-sources", + "-Xcheck-phase-conditions", + "-Xcheck-sticky-phase-conditions", + "-Xcommon-sources", + "-Xcompile-java", + "-Xcontext-receivers", + "-Xdebug", + "-Xdefault-script-extension", + "-Xdisable-default-scripting-plugin", + "-Xdisable-phases", + "-Xdisable-standard-script", + "-Xdisable-ultra-light-classes", + "-Xeffect-system", + "-Xemit-jvm-type-annotations", + "-Xenable-builder-inference", + "-Xenable-incremental-compilation", + "-Xenhance-type-parameter-types-to-def-not-null", + "-Xexpect-actual-linker", + "-Xexplicit-api", + "-Xextended-compiler-checks", + "-Xfriend-paths", + "-Xgenerate-strict-metadata-version", + "-Xignore-const-optimization-errors", + "-Xinference-compatibility", + "-Xinline-classes", + "-Xir-do-not-clear-binding-context", + "-Xjava-package-prefix", + "-Xjava-source-roots", + "-Xjavac-arguments", + "-Xjdk-release", + "-Xjspecify-annotations", + "-Xjsr305", + "-Xjvm-default", + "-Xjvm-enable-preview", + "-Xklib", + "-Xklib-enable-signature-clash-checks", + "-Xklib-normalize-absolute-path", + "-Xklib-relative-path-base", + "-Xlambdas", + "-Xlegacy-smart-cast-after-try", + "-Xlink-via-signatures", + "-Xlist-phases", + "-Xmetadata-version", + "-Xmodule-path", + "-Xmulti-platform", + "-Xmultifile-parts-inherit", + "-Xnew-inference", + "-Xno-call-assertions", + "-Xno-check-actual", + "-Xno-inline", + "-Xno-kotlin-nothing-value-exception", + "-Xno-new-java-annotation-targets", + "-Xno-optimize", + "-Xno-optimized-callable-references", + "-Xno-param-assertions", + "-Xno-receiver-assertions", + "-Xno-reset-jar-timestamps", + "-Xno-source-debug-extension", + "-Xno-unified-null-checks", + "-Xnullability-annotations", + "-Xphases-to-dump", + "-Xphases-to-dump-after", + "-Xphases-to-dump-before", + "-Xphases-to-validate", + "-Xphases-to-validate-after", + "-Xphases-to-validate-before", + "-Xprofile", + "-Xprofile-phases", + "-Xproper-ieee754-comparisons", + "-Xread-deserialized-contracts", + "-Xrender-internal-diagnostic-names", + "-Xrepeat", + "-Xreport-output-files", + "-Xreport-perf", + "-Xsam-conversions", + "-Xsanitize-parentheses", + "-Xscript-resolver-environment", + "-Xself-upper-bound-inference", + "-Xserialize-ir", + "-Xskip-metadata-version-check", + "-Xskip-prerelease-check", + "-Xstring-concat", + "-Xsupport-compatqual-checker-framework-annotations", + "-Xsuppress-deprecated-jvm-target-warning", + "-Xsuppress-missing-builtins-error", + "-Xsuppress-version-warnings", + "-Xtype-enhancement-improvements-strict-mode", + "-Xunrestricted-builder-inference", + "-Xuse-14-inline-classes-mangling-scheme", + "-Xuse-fast-jar-file-system", + "-Xuse-fir-extended-checkers", + "-Xuse-fir-ic", + "-Xuse-fir-lt", + "-Xuse-ir", + "-Xuse-javac", + "-Xuse-k2", + "-Xuse-mixed-named-arguments", + "-Xuse-old-backend", + "-Xuse-old-class-files-reading", + "-Xuse-old-innerclasses-logic", + "-Xuse-type-table", + "-Xvalidate-bytecode", + "-Xvalidate-ir", + "-Xvalue-classes", + "-Xverbose-phases", + "-api-version", + "-java-parameters", + "-jvm-target", + "-language-version", + "-no-reflect", + "-nowarn", + "-opt-in", + "-progressive", + "-verbose", + "-version", +] diff --git a/src/main/starlark/core/repositories/versions.bzl b/src/main/starlark/core/repositories/versions.bzl index 978408a72..6cd123575 100644 --- a/src/main/starlark/core/repositories/versions.bzl +++ b/src/main/starlark/core/repositories/versions.bzl @@ -63,18 +63,18 @@ versions = struct( sha256 = "2b3f6f674a944d25bb8d283c3539947bbe86074793012909a55de4b771f74bcc", ), KOTLIN_CURRENT_COMPILER_RELEASE = version( - version = "1.8.21", + version = "1.9.10", url_templates = [ "https://github.com/JetBrains/kotlin/releases/download/v{version}/kotlin-compiler-{version}.zip", ], - sha256 = "6e43c5569ad067492d04d92c28cdf8095673699d81ce460bd7270443297e8fd7", + sha256 = "7d74863deecf8e0f28ea54c3735feab003d0eac67e8d3a791254b16889c20342", ), KSP_CURRENT_COMPILER_PLUGIN_RELEASE = version( - version = "1.8.21-1.0.11", + version = "1.9.10-1.0.13", url_templates = [ "https://github.com/google/ksp/releases/download/{version}/artifacts.zip", ], - sha256 = "81a609b48fddd4431bac2abe3570e36f79b1266672be30b581a0595c3fb2e615", + sha256 = "5b0b1179e8af40877d9d5929ec0260afb104956eabf2f23bb5568cfd6c20b37b", ), ANDROID = struct( VERSION = "0.1.1", diff --git a/src/test/data/jvm/basic/helloworld/Main.kt b/src/test/data/jvm/basic/helloworld/Main.kt index 5d6b94427..b8e029bee 100644 --- a/src/test/data/jvm/basic/helloworld/Main.kt +++ b/src/test/data/jvm/basic/helloworld/Main.kt @@ -19,7 +19,7 @@ package helloworld import java.nio.file.Paths -fun main(args: Array) { +fun main() { if (!Paths.get("tests", "smoke", "data", "datafile.txt").toFile().exists()) { System.err.println("could not read datafile") System.exit(1) diff --git a/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java b/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java index dc1a804b2..f64de1578 100644 --- a/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java +++ b/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java @@ -96,7 +96,7 @@ public final List outLines() { public final void resetForNext() { outLines = null; - label = "a_test_" + counter.incrementAndGet(); + label = "a-test-" + counter.incrementAndGet(); infoBuilder .setLabel("//some/bogus:" + label()) .setModuleName("some_bogus_module") @@ -106,9 +106,9 @@ public final void resetForNext() { KotlinToolchainInfo.newBuilder() .setCommon( KotlinToolchainInfo.Common.newBuilder() - .setApiVersion("1.6") + .setApiVersion("1.8") .setCoroutines("enabled") - .setLanguageVersion("1.6")) + .setLanguageVersion("1.8")) .setJvm(KotlinToolchainInfo.Jvm.newBuilder().setJvmTarget("1.8"))); try { this.instanceRoot = Files.createTempDirectory(BAZEL_TEST_DIR, label); @@ -129,6 +129,11 @@ public final void setDebugTags(String... tags) { final Path writeFile(DirectoryType dirType, String filename, String[] lines) { Path path = directory(dirType).resolve(filename).toAbsolutePath(); + try { + Files.createDirectories(path.getParent()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } try (FileOutputStream fos = new FileOutputStream(path.toFile())) { fos.write(String.join("\n", lines).getBytes(UTF_8)); } catch (IOException e) { @@ -137,6 +142,8 @@ final Path writeFile(DirectoryType dirType, String filename, String[] lines) { return path; } + + public final Path writeSourceFile(String filename, String[] lines) { return writeFile(DirectoryType.SOURCES, filename, lines); } @@ -162,7 +169,6 @@ private R runCompileTask( .lines() .collect(toList())); } - } public final void assertFilesExist(DirectoryType dir, String... paths) { diff --git a/src/test/kotlin/io/bazel/kotlin/builder/KotlinJsTestBuilder.java b/src/test/kotlin/io/bazel/kotlin/builder/KotlinJsTestBuilder.java index fc89b6b0e..9707c817c 100644 --- a/src/test/kotlin/io/bazel/kotlin/builder/KotlinJsTestBuilder.java +++ b/src/test/kotlin/io/bazel/kotlin/builder/KotlinJsTestBuilder.java @@ -17,59 +17,81 @@ import io.bazel.kotlin.model.CompilationTaskInfo; import io.bazel.kotlin.model.JsCompilationTask; - +import java.io.IOException; +import java.nio.file.Files; import java.util.Arrays; import java.util.EnumSet; import java.util.List; import java.util.function.Consumer; public final class KotlinJsTestBuilder extends KotlinAbstractTestBuilder { - private static final List PASSTHROUGH_FLAGS = - Arrays.asList("-source-map", "-meta-info", "-module-kind", "commonjs", "-target", "v5"); - private static final JsCompilationTask.Builder taskBuilder = JsCompilationTask.newBuilder(); - private static final KotlinBuilderComponent component = - DaggerKotlinBuilderComponent.builder().toolchain(toolchainForTest()).build(); - private static final EnumSet ALL_DIRECTORY_TYPES = - EnumSet.of(DirectoryType.SOURCES); - private final TaskBuilder taskBuilderInstance = new TaskBuilder(); + private static final List PASSTHROUGH_FLAGS = + Arrays.asList("-source-map", "-module-kind", "commonjs", "-target", "v5", "-Xir-produce-klib-dir"); + private static final JsCompilationTask.Builder taskBuilder = JsCompilationTask.newBuilder(); + private static final KotlinBuilderComponent component = + DaggerKotlinBuilderComponent.builder().toolchain(toolchainForTest()).build(); + private static final EnumSet ALL_DIRECTORY_TYPES = + EnumSet.allOf(DirectoryType.class); + private final TaskBuilder taskBuilderInstance = new TaskBuilder(); + + @Override + JsCompilationTask buildTask() { + return taskBuilder.build(); + } - @Override - JsCompilationTask buildTask() { - return taskBuilder.build(); + @Override + void setupForNext(CompilationTaskInfo.Builder infoBuilder) { + taskBuilder.clear().setInfo(infoBuilder); + DirectoryType.createAll(instanceRoot(), ALL_DIRECTORY_TYPES); + taskBuilder.addAllPassThroughFlags(PASSTHROUGH_FLAGS); + try { + taskBuilder.getDirectoriesBuilder().setTemp( + Files.createDirectories(directory(DirectoryType.TEMP).resolve("working")).toString()); + } catch (IOException e) { + throw new RuntimeException(e); } + taskBuilder + .getOutputsBuilder() + .setJar(directory(DirectoryType.TEMP).resolve(label() + ".jar").toAbsolutePath().toString()) + .setSrcjar(directory(DirectoryType.TEMP).resolve(label() + "-sources.jar").toAbsolutePath().toString()) + .setJs(directory(DirectoryType.TEMP).resolve(label() + ".js").toAbsolutePath().toString()); + } + + public String runCompilationTask(Consumer setup, Consumer> outlines) { + resetForNext(); + setup.accept(taskBuilderInstance); + try { + return runCompileTask( + (taskContext, task) -> { + component.jsTaskExecutor().execute(taskContext, task); + String jsFile = task.getOutputs().getJs(); + assertFilesExist( + jsFile, + jsFile + ".map", + task.getOutputs().getJar(), + task.getOutputs().getSrcjar()); + return task.getOutputs().getJar(); + }); + } finally{ + outlines.accept(outLines()); + } + } + + public void runCompilationTask(Consumer setup) { + runCompilationTask(setup, l -> {}); + } - @Override - void setupForNext(CompilationTaskInfo.Builder infoBuilder) { - taskBuilder.clear().setInfo(infoBuilder); - DirectoryType.createAll(instanceRoot(), ALL_DIRECTORY_TYPES); - taskBuilder.addAllPassThroughFlags(PASSTHROUGH_FLAGS); - taskBuilder - .getOutputsBuilder() - .setJar(instanceRoot().resolve(label() + ".jar").toAbsolutePath().toString()) - .setSrcjar(instanceRoot().resolve(label() + "-sources.jar").toAbsolutePath().toString()) - .setJs(instanceRoot().resolve(label() + ".js").toAbsolutePath().toString()); + public final class TaskBuilder { + public void addSource(String filename, String... lines) { + taskBuilder.getInputsBuilder().addKotlinSources(writeSourceFile(filename, lines).toString()); } - public void runCompilationTask(Consumer setup) { - resetForNext(); - setup.accept(taskBuilderInstance); - runCompileTask( - (taskContext, task) -> { - component.jsTaskExecutor().execute(taskContext, task); - String jsFile = task.getOutputs().getJs(); - assertFilesExist( - jsFile, - jsFile + ".map", - jsFile.substring(0, jsFile.length() - 3) + ".meta.js", - task.getOutputs().getJar(), - task.getOutputs().getSrcjar()); - return null; - }); + public void addDependency(String filename) { + taskBuilder.getInputsBuilder().addLibraries(filename); } - public final class TaskBuilder { - public void addSource(String filename, String... lines) { - taskBuilder.getInputsBuilder().addKotlinSources(writeSourceFile(filename, lines).toString()); - } + public void addArg(String flag) { + taskBuilder.addPassThroughFlags(flag ); } + } } diff --git a/src/test/kotlin/io/bazel/kotlin/builder/tasks/BUILD.bazel b/src/test/kotlin/io/bazel/kotlin/builder/tasks/BUILD.bazel index 34982d6ed..ff8057393 100644 --- a/src/test/kotlin/io/bazel/kotlin/builder/tasks/BUILD.bazel +++ b/src/test/kotlin/io/bazel/kotlin/builder/tasks/BUILD.bazel @@ -90,6 +90,11 @@ kt_rules_test( kt_rules_test( name = "KotlinBuilderJsTest", srcs = ["js/KotlinBuilderJsTest.java"], + args = [ + ], + data = [ + "@com_github_jetbrains_kotlin//:lib/kotlin-stdlib-js.jar", + ], ) test_suite( diff --git a/src/test/kotlin/io/bazel/kotlin/builder/tasks/js/KotlinBuilderJsTest.java b/src/test/kotlin/io/bazel/kotlin/builder/tasks/js/KotlinBuilderJsTest.java index 9b2354ca8..56450d0e7 100644 --- a/src/test/kotlin/io/bazel/kotlin/builder/tasks/js/KotlinBuilderJsTest.java +++ b/src/test/kotlin/io/bazel/kotlin/builder/tasks/js/KotlinBuilderJsTest.java @@ -1,5 +1,6 @@ package io.bazel.kotlin.builder.tasks.js; +import io.bazel.kotlin.builder.Deps.Dep; import io.bazel.kotlin.builder.KotlinJsTestBuilder; import org.junit.Test; import org.junit.runner.RunWith; @@ -9,20 +10,64 @@ @RunWith(JUnit4.class) public class KotlinBuilderJsTest { - private static final KotlinJsTestBuilder builder = new KotlinJsTestBuilder(); - - @Test - public void testSimpleJsCompile() { - builder.runCompilationTask( - it -> it.addSource("AClass.kt", "package something", "class AClass{}")); - } - - @Test - public void testJsErrorRendering() { - builder.runFailingCompileTaskAndValidateOutput( - () -> - builder.runCompilationTask( - it -> it.addSource("AClass.kt", "package something", "class AClass{")), - lines -> assertThat(lines).contains(builder.toPlatform("sources/AClass.kt:2:14: error: missing '}"))); - } + private static final KotlinJsTestBuilder builder = new KotlinJsTestBuilder(); + + private Dep stdLib = Dep.fromLabel("@com_github_jetbrains_kotlin//:lib/kotlin-stdlib-js.jar"); + + @Test + public void testSimpleJsCompile() { + builder.runCompilationTask( + it -> { + it.addDependency(stdLib.singleCompileJar()); + it.addArg("-Xreport-output-files"); + it.addArg("-Xreport-perf"); + it.addArg("-verbose"); + it.addSource( + "AClass.kt", + "package something", + "class AClass{", + " fun foo() : String {", + " return \"bar\"", + " }", + "}"); + }, + lines -> { + lines.forEach(System.out::println); + }); + } + + @Test + public void testFuncJsCompile() { + + builder.runCompilationTask( + it -> { + it.addDependency(stdLib.singleCompileJar()); + it.addArg("-Xreport-output-files"); + it.addArg("-Xreport-perf"); + it.addArg("-verbose"); + it.addSource( + "auth/Auth.kt", + "package express.something", + "fun isAuthenticated(user: String): Boolean {", + " return user != \"bob\"", + "}"); + }, + lines -> { + lines.forEach(System.out::println); + }); + } + + @Test + public void testJsErrorRendering() { + builder.runFailingCompileTaskAndValidateOutput( + () -> + builder.runCompilationTask( + it -> { + it.addSource("AClass.kt", "package something", "class AClass{"); + it.addDependency(stdLib.singleCompileJar()); + }), + lines -> + assertThat(lines) + .contains("sources/AClass.kt:2:14: error: missing '}")); + } } diff --git a/src/test/kotlin/io/bazel/kotlin/builder/tasks/jvm/KotlinBuilderJvmBasicTest.java b/src/test/kotlin/io/bazel/kotlin/builder/tasks/jvm/KotlinBuilderJvmBasicTest.java index 05ee4cf28..d428f5778 100644 --- a/src/test/kotlin/io/bazel/kotlin/builder/tasks/jvm/KotlinBuilderJvmBasicTest.java +++ b/src/test/kotlin/io/bazel/kotlin/builder/tasks/jvm/KotlinBuilderJvmBasicTest.java @@ -59,26 +59,26 @@ private static String hashDep(String path) { public void testSimpleMixedModeCompile() { ctx.runCompileTask( c -> { - c.compileKotlin(); - c.addSource( - "AClass.kt", - "package something;" + "class AClass{}" - ); - c.outputJar(); - c.outputJdeps(); - }); + c.compileKotlin(); + c.addSource( + "AClass.kt", + "package something;" + "class AClass{}" + ); + c.outputJar(); + c.outputJdeps(); + }); ctx.assertFilesExist(DirectoryType.CLASSES, "something/AClass.class"); } @Test public void testGeneratesJDeps() { - ctx.runCompileTask( - c -> { - c.addSource("AClass.kt", "package something;" + "class AClass{}"); - // declaring outputJdeps also asserts existance after compile. - c.outputJar().outputJdeps().compileKotlin(); - }); - } + ctx.runCompileTask( + c -> { + c.addSource("AClass.kt", "package something;" + "class AClass{}"); + // declaring outputJdeps also asserts existance after compile. + c.outputJar().outputJdeps().compileKotlin(); + }); + } @Test public void testKotlinErrorRendering() {