Skip to content

Commit

Permalink
Add support for Kotlin 1.9 (#996)
Browse files Browse the repository at this point in the history
*NOTE:* JS support is currently inoperable with 1.9. We are debating continued support.

* Add support for Kotlin 1.9
* Disable js example for RC.



Co-authored-by: Corbin McNeely-Smith <restingbull@mcneely-smith.com>
Co-authored-by: Corbin McNeely-Smith <58151731+restingbull@users.noreply.github.com>
  • Loading branch information
3 people authored Oct 18, 2023
1 parent eb251f9 commit 55f60ec
Show file tree
Hide file tree
Showing 21 changed files with 386 additions and 177 deletions.
20 changes: 10 additions & 10 deletions .bazelci/presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
```

Expand Down
4 changes: 4 additions & 0 deletions examples/node/express/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ kt_js_library(
kt_js_library(
name = "app",
srcs = [":App.kt"],
tags = [
"timings",
"trace",
],
deps = [
":acme-routes",
"//:kotlinx-coroutines-core",
Expand Down
1 change: 1 addition & 0 deletions examples/node/express/auth/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
)
15 changes: 2 additions & 13 deletions kotlin/internal/js/impl.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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",
Expand All @@ -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")
Expand All @@ -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"},
Expand Down
2 changes: 2 additions & 0 deletions kotlin/internal/toolchains.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ _kt_toolchain = rule(
"1.6",
"1.7",
"1.8",
"1.9",
],
),
"api_version": attr.string(
Expand All @@ -148,6 +149,7 @@ _kt_toolchain = rule(
"1.6",
"1.7",
"1.8",
"1.9",
],
),
"debug": attr.string_list(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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<String>().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<String>().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<Path>) {
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) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/io/bazel/kotlin/plugin/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
)

Expand Down
24 changes: 10 additions & 14 deletions src/main/kotlin/io/bazel/kotlin/plugin/SkipCodeGen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"
}

/**
Expand All @@ -71,7 +67,7 @@ class SkipCodeGen : ComponentRegistrar {
module: ModuleDescriptor,
bindingTrace: BindingTrace,
files: Collection<KtFile>,
): AnalysisResult? {
): AnalysisResult {
// Ensure this is the last plugin, as it will short circuit any other plugin analysisCompleted
// calls.
Preconditions.checkState(
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/io/bazel/kotlin/plugin/jdeps/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
)
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions src/main/starlark/core/repositories/compiler.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Loading

0 comments on commit 55f60ec

Please sign in to comment.