What's new in Kotlin 1.5.20
Kotlin 1.5.20 has fixes for issues discovered in the new features of 1.5.0, and it also includes various tooling improvements.
You can find an overview of the changes in the release blog post and this video:
Kotlin 1.5.20 is receiving the following updates on the JVM platform:
String concatenation via invokedynamic
Kotlin 1.5.20 compiles string concatenations into dynamic invocations (
invokedynamic) on JVM 9+ targets, thereby keeping up with modern Java versions. More precisely, it uses
StringConcatFactory.makeConcatWithConstants() for string concatenation.
To switch back to concatenation via
StringBuilder.append() used in previous versions, add the compiler option
Support for JSpecify nullness annotations
The Kotlin compiler can read various types of nullability annotations to pass nullability information from Java to Kotlin. Version 1.5.20 introduces support for the JSpecify project, which includes the standard unified set of Java nullness annotations.
With JSpecify, you can provide more detailed nullability information to help Kotlin keep null-safety interoperating with Java. You can set default nullability for the declaration, package, or module scope, specify parametric nullability, and more. You can find more details about this in the JSpecify user guide.
Here is the example of how Kotlin can handle JSpecify annotations:
In 1.5.20, all nullability mismatches according to the JSpecify-provided nullability information are reported as warnings. Use the
-Xtype-enhancement-improvements-strict-mode compiler options to enable strict mode (with error reporting) when working with JSpecify. Please note that the JSpecify project is under active development. Its API and implementation can change significantly at any time.
Support for calling Java’s Lombok-generated methods within modules that have Kotlin and Java code
Kotlin 1.5.20 introduces an experimental Lombok compiler plugin. This plugin makes it possible to generate and use Java’s Lombok declarations within modules that have Kotlin and Java code. Lombok annotations work only in Java sources and are ignored if you use them in Kotlin code.
The plugin supports the following annotations:
We're continuing to work on this plugin. To find out the detailed current state, visit the Lombok compiler plugin's README.
Currently, we don't have plans to support the
@Builder annotation. However, we can consider this if you vote for
@Builder in YouTrack.
Kotlin/Native 1.5.20 offers a preview of the new feature and the tooling improvements:
Opt-in export of KDoc comments to generated Objective-C headers
You can now set the Kotlin/Native compiler to export the documentation comments (KDoc) from Kotlin code to the Objective-C frameworks generated from it, making them visible to the frameworks’ consumers.
For example, the following Kotlin code with KDoc:
produces the following Objective-C headers:
This also works well with Swift.
To try out this ability to export KDoc comments to Objective-C headers, use the
-Xexport-kdoc compiler option. Add the following lines to
build.gradle(.kts) of the Gradle projects you want to export comments from:
We’d be very grateful if you would share your feedback with us using this YouTrack ticket.
Compiler bug fixes
The Kotlin/Native compiler has received multiple bug fixes in 1.5.20. You can find the complete list in the changelog.
There is an important bug fix that affects compatibility: in previous versions, string constants that contained incorrect UTF surrogate pairs were losing their values during compilation. Now such values are preserved. Application developers can safely update to 1.5.20 – nothing will break. However, libraries compiled with 1.5.20 are incompatible with earlier compiler versions. See this YouTrack issue for details.
Improved performance of Array.copyInto() inside one array
We’ve improved the way
Array.copyInto() works when its source and destination are the same array. Now such operations finish up to 20 times faster (depending on the number of objects being copied) due to memory management optimizations for this use case.
With 1.5.20, we’re publishing a guide that will help you migrate your projects to the new IR-based backend for Kotlin/JS.
Migration guide for the JS IR backend
The new migration guide for the JS IR backend identifies issues you may encounter during migration and provides solutions for them. If you find any issues that aren’t covered in the guide, please report them to our issue tracker.
Kotlin 1.5.20 introduces the following features that can improve the Gradle experience:
Caching for annotation processors' classloaders in kapt
There is now a new experimental feature that makes it possible to cache the classloaders of annotation processors in kapt. This feature can increase the speed of kapt for consecutive Gradle runs.
To enable this feature, use the following properties in your
Learn more about kapt.
Deprecation of the kotlin.parallel.tasks.in.project build property
With this release, Kotlin parallel compilation is controlled by the Gradle parallel execution flag
--parallel. Using this flag, Gradle executes tasks concurrently, increasing the speed of compiling tasks and utilizing the resources more efficiently.
You no longer need to use the
kotlin.parallel.tasks.in.project property. This property has been deprecated and will be removed in the next major release.
Kotlin 1.5.20 changes the platform-specific implementations of several functions for working with characters and as a result brings unification across platforms:
Support for all Unicode digits in Char.digitToInt() in Kotlin/Native and Kotlin/JS
Char.digitToInt() returns the numeric value of the decimal digit that the character represents. Before 1.5.20, the function supported all Unicode digit characters only for Kotlin/JVM: implementations on the Native and JS platforms supported only ASCII digits.
From now, both with Kotlin/Native and Kotlin/JS, you can call
Char.digitToInt() on any Unicode digit character and get its numeric representation.
Unification of Char.isLowerCase()/isUpperCase() implementations across platforms
Char.isLowerCase() return a boolean value depending on the case of the character. For Kotlin/JVM, the implementation checks both the
General_Category and the
Other_Lowercase Unicode properties.
Prior to 1.5.20, implementations for other platforms worked differently and considered only the general category. In 1.5.20, implementations are unified across platforms and use both properties to determine the character case: