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/JVM
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 -Xstring-concat=inline
.
Learn how to add compiler options in Gradle, Maven, and the command-line compiler.
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 -Xjspecify-annotations=strict
and -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:
@Getter
,@Setter
@NoArgsConstructor
,@RequiredArgsConstructor
, and@AllArgsConstructor
@Data
@With
@Value
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
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 would 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.
Kotlin/JS
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.
Gradle
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 gradle.properties
file:
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.
Standard library
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() for Kotlin/Native and Kotlin/JS.
Unification of Char.isLowerCase()/isUpperCase() implementations 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
The functions Char.isUpperCase()
and 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_Uppercase
/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: