Kotlin 1.3.20 released

Posted on by

We’re happy to announce the release of Kotlin 1.3.20, a new bug fix and tooling update for Kotlin 1.3. In addition to improvements to the compiler and IDE, this version:

Allows running Gradle tasks in parallel within a single project

Allows building multiplatform projects via Gradle Kotlin DSL

Brings improvements for inline classes

Introduces a separate command line tool for Kapt

Enables incremental compilation for Kotlin/JS by default

Brings improvements to Kotlin/Native

As always, we’d like to thank our numerous external contributors. The complete list of changes for this release can be found in the change log. Let’s dive in!

Faster Gradle builds by parallelizing tasks

The Kotlin Gradle plugin can now run tasks in parallel within a project. Parallel execution is supported by using the Gradle Worker API. To make use of this feature, add the following setting to gradle.properties or local.properties file:

kotlin.parallel.tasks.in.project=true

This feature is beneficial for projects defining custom source sets, since the compilation of independent source sets can be parallelized. In the case of multiplatform projects, targets for different platforms can also be built in parallel. For Android, the debug and release build types can be compiled in parallel.

We plan to enable the parallel task compilation by default at a later date, so we kindly ask for your feedback. Do let us know if you face any issues.

Multiplatform projects update

We continue working on multiplatform projects and improve different aspects based on your feedback.

Support for Kotlin Gradle DSL

You can now use Kotlin Gradle DSL to build multiplatform projects:

plugins { kotlin("multiplatform") version "1.3.20" } ... kotlin { ... sourceSets { val commonMain by getting { dependencies { implementation(kotlin("stdlib-common")) } } }

You can check many examples in both Groovy and Kotlin in the documentation.

DSL improvements

The DSL to set up a multiplatform project has been greatly improved and simplified. This blog post contains some highlights in comparison to the previous version. We recommend you read the updated guide for more details and complete samples.

You can now use shorthand for Kotlin dependencies. That is, instead of 'org.jetbrains.kotlin:kotlin-stdlib' you write simply kotlin('stdlib') .

In addition, supported targets can be specified directly instead of using the fromPreset function:

// prior kotlin { targets { fromPreset(presets.jvm, 'jvm') fromPreset(presets.js, 'nodeJs') { /* additional configuration */ } } }

// currently kotlin { jvm() js('nodeJs') { /* additional configuration */ } // get the existing target: def theJsTarget = js('nodeJs') }

Note that if you need it, the previous functionality still exists, using targetFromPreset(...) .

You can also independently configure Kotlin/Native binaries like executable files or native libraries. For instance, you can use this to export symbols of certain dependencies to an Objective-C framework.

kotlin { macosX64 { binaries { // Produce the framework and export the dependency. framework { export(project(":dependency")) } } } }

For more information, please refer to the documentation.

Finally, we’ve also made kotlinOptions available, allowing for easier compiler configuration

compilations.all { kotlinOptions { freeCompilerArgs = ["-progressive", "-Xskip-metadata-version-check"] } }

All improvements are available both in Groovy and Kotlin DSL.

Android Library (AAR) can be a part of a multiplatform library

You can now publish Android libraries (AAR) as a part of a multiplatform library. This functionality is disabled by default; to enable it, specify the list of the variants that you want to publish in the scope of the Android target:

kotlin { android { publishLibraryVariants("release", "debug") } }

You can read more about publishing libraries in the documentation.

Improvements for inline classes

Support for inline classes has been significantly improved, and some constraints have been mitigated. For instance, you can now define an inner class inside an inline class. There are also improvements for non-trivial cases, like using inline functions inside inline classes or passing references to inline classes as arguments to inline functions.

You can now also use reflection with inline classes and have access to class literals and javaClass property

inline class Duration(val seconds: Int) fun test(duration: Duration) { // the following expressions are translated into class objects for "Duration" class Duration::class duration::class duration.javaClass assertEquals(duration::class.toString(), "class Duration") assertEquals(Duration::class.simpleName, "Duration") }

There’s also support for call and callBy for functions that have inline class types in their signature. For more information, refer to the corresponding section on the KEEP.

Kotlin/Native

Code contracts

Some time ago we introduced experimental support for contracts, which allows a function to describe its behaviour in a way that the compiler understands. This functionality is now also available in Kotlin/Native.

Better interop

Improved interop including support for more C constructions such as enums with forward declarations, as well as better error reporting for cases of inheritance in Objective-C.

Native frameworks from libraries

With this release, we can now produce Apple frameworks not only from source files but also from Kotlin libraries (i.e. .klib files). This is possible using the -Xexport-library command line option or via Gradle plugins

Performance

Apart from reducing the memory footprint and improving runtime performance, this release also brings compiler optimizations for looping over ranges, making iterations much faster.

IntelliJ IDEA support

This release adds new refactorings, inspections, and intentions to the IntelliJ IDEA plugin. We’ll highlight some of them.

Template to generate main without parameters

Since Kotlin 1.3, you can use the main function without parameters. Now, the default ‘main’ live template adds this new version of main .

If you need to pass some arguments, use ‘maina’ live template.

Inspections to improve coroutines code

When working with coroutines, you usually follow certain conventions. For instance, you would add an “Async” suffix to a function returning ‘Deferred’, or define a function either as a suspend one or as an extension to CoroutineScope , but never both at the same time (for more details, check this talk from KotlinConf). IntelliJ IDEA is now aware of these conventions and offers intentions to fix potential issues:

New intention for converting SAM as lambda to an anonymous object

A new intention allows to convert constructs using lambdas with SAM to anonymous objects. For instance

val runnable = Runnable { action() }

can now be converted automatically by the IDE to

val runnable = object : Runnable { override fun run() { action() } }

String conversion improvements

‘Convert concatenation to template’ intention is now smarter, meaning

class Card(val suit: Any, val value: Any) { override fun toString(): String = value.toString() + suit.toString() }

will be converted to

class Card(val suit: Any, val value: Any) { override fun toString(): String = "$value$suit" }

removing the unnecessary .toString() calls on each parameter.

Kapt improvements

Using Kapt from the command line has been simplified, allowing for direct use as a separate command line tool as opposed to having to use it via the compiler:

// prior kotlinc -Xplugin=$KOTLIN_HOME/lib/kotlin-annotation-processing.jar ... // currently kapt ...

All kapt-related arguments are now passed as top-level arguments instead of using the verbose syntax:

// prior -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=<classpath> // currently -Kapt-classpath=<classpath>

Note that a new option that shows processor timings (-Kapt-show-processor-timings`) has also been introduced in this release.

Compile avoidance for kapt

We’ve added support for Compile Avoidance for kaptKotlin tasks in Gradle, improving build performance times. It skips annotation processing completely when there are no changes in kapt stubs and only method bodies are changed in dependencies. Setting

kapt.include.compile.classpath=false

in gradle.properties enables it. Note, however, that this setting also turns off the AP discovery in compile classpath, but if you add AP to kapt* configuration, that shouldn’t affect you.

Other notable mentions

In addition to the above, a few more fixes and improvements worth mentioning:

Incremental compilation for Kotlin/JS is now stable enough and is enabled by default. If you encounter any issues, we’d appreciate if you report it to us, and in the meantime, you can disable the option: In a Gradle project, add kotlin.incremental.js=false to gradle.properties or local.properties In an IntelliJ IDEA project, go to Settings | Build, Execution, Deployment | Compiler | Kotlin Compiler | Kotlin to JavaScript and uncheck Enable incremental compilation .

We now provide a Kotlin BOM (Bill of Materials) file that lists the dependencies used from the org.jetbrains.kotlin group.

group. Stable sorting is now available on all targets. Previously this was an issue when targeting JavaScript.

Numerous fixes and improvements in scripting support.

Support for MethodHandle and VarHandle in JVM code generation.

Modularized artifacts for Kotlin JVM libraries are included.

Kotlin/Native will embed bitcode by default for iOS frameworks targets in Gradle projects.

Kotlin/Native annotations @ThreadLocal and @SharedImmutable are now accessible from common code (declared as optional expect ).

How to update

To update your IntelliJ IDEA or Android Studio plugin, use Tools | Kotlin | Configure Kotlin Plugin Updates and click the “Check for updates now” button. The Eclipse IDE plugin can be installed or updated via the Eclipse Marketplace (Help | Eclipse Marketplace and search for the Kotlin plugin).

Also, don’t forget to update the compiler and standard library versions in your Maven and Gradle build scripts. As usual, if you run into any problems with the new release, you’re welcome to ask for help on the forums, on Slack (get an invite here), or to report issues in the issue tracker.

Let’s Kotlin!

External Contributions

Thank you once again to all community contributions for this release. In particular:

Updates

We previously stated that it is necessary to enable parallel builds in Gradle using

org.gradle.parallel=true

This is in fact not required, as this would enable cross-project parallelism. Thank you to Cédric Champeau and Eric Wendelin for pointing this out.