Auto Added by WPeMatico

Kotlin 1.9.20 Released

The Kotlin 1.9.20 release is out, the K2 compiler for all the targets is now in Beta, and Kotlin Multiplatform is now Stable.

Here are some highlights from this release:

  • K2 is now in Beta for all the targets
  • Stable Kotlin Multiplatform
  • New default hierarchy template for setting up multiplatform projects
  • Full support for the Gradle configuration cache in Kotlin Multiplatform
  • Custom memory allocator enabled by default in Kotlin/Native
  • Performance improvements for the garbage collector in Kotlin/Native
  • New and renamed targets in Kotlin/Wasm, support for the latest Wasm GC
  • Support for the WASI API in the standard library for Kotlin/Wasm

For the complete list of changes, refer to What’s new in Kotlin 1.9.20 or the release notes on GitHub.

The New Kotlin K2 Compiler Is Beta for All Targets

The Kotlin team at JetBrains is continuing to stabilize the new K2 compiler, which will bring major performance improvements, speed up new language feature development, unify all platforms that Kotlin supports, and provide a better architecture for multiplatform projects. 

With the 1.9.20 release, the new K2 compiler has reached the Beta stage for all platforms: JVM, Native, JS, and Wasm. This means that you can now try K2 in any Kotlin project.

The Kotlin team has ensured the quality of the new compiler by successfully compiling dozens of user and internal projects. A large number of users are also involved in the stabilization process, trying out the new K2 compiler in their projects and reporting any problems they find.

The Kotlin 1.9.20 release also brings K2 support in the kapt compiler plugin. Now, all essential Kotlin compiler plugins have K2 support. These include kapt, serialization, AtomicFU, Lombok, SAM with receiver, all-open, no-arg, jvm-abi-gen, Android Lint, and the Jetpack Compose compiler plugin. Kotlin Symbol Processing (KSP) with K2 support will be released within a week after Kotlin 1.9.20.

If you use any additional compiler plugins, check their documentation to see if they are compatible with K2.

The next stop is Kotlin 2.0

The next major version of Kotlin is 2.0.0, with the new K2 compiler as the default and stable for all targets.

To address any issues found as quickly as possible, we have planned a series of small, frequent Kotlin 2.0 stabilization releases. These releases will include Beta1, Beta2, Beta3, RC1, and RC2.

At the time of the Kotlin 2.0.0-RC1 release, we plan to ensure binary compatibility with code compiled by other versions of the Kotlin compilers and eliminate poisoning of binaries compiled with K2. This will enable you to use the new K2 compiler in production environments.

Get involved: shape Kotlin 2.0 and try the K2 compiler today

The K2 Compiler is on the verge of completing its stabilization process and becoming enabled by default in Kotlin 2.0. It is crucial that as many developers as possible give K2 a try and report any potential issues. 

Your feedback will help us address any problems and ensure that K2 performs flawlessly, even in the most complex scenarios. Just a single compilation of your project using K2 can significantly contribute to reaching the Kotlin 2.0 milestone. Give K2 a try today!

Try the K2 compiler

How to install Kotlin 1.9.20

If you already use IntelliJ IDEA 2023.1, 2023.2, the IDE will suggest updating Kotlin to 1.9.20 automatically. You can also update manually by following these instructions. IntelliJ IDEA 2023.3 will include the Kotlin 1.9.20 plugin.

For Android Studio Hedgehog (231) and Iguana (232), the Kotlin 1.9.20 plugin will be included in upcoming Android Studios updates. If you need the command-line compiler, download it from the GitHub release page.

If you run into any problems

  • Report issues to our issue tracker, YouTrack.

Special thanks to our EAP Champions 🥇👏

Stay up to date with the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form at the bottom of this post. ⬇️

What else to read and watch

Continue ReadingKotlin 1.9.20 Released

Kotlin 1.8.0 Released

The Kotlin 1.8.0 release is out and here are some of its biggest highlights:

Read the complete list of changes in What’s new in Kotlin 1.8.0.


How to install Kotlin 1.8.0

If you already use IntelliJ IDEA (2021.3, 2022.1, 2022.2), your IDE will suggest updating Kotlin to 1.8.0 automatically. You can also update manually for these IDEs by following these instructions.

For IntelliJ IDEA 2022.3, the Kotlin plugin 1.8.0 will be delivered with upcoming IntelliJ IDEA updates.

For Android Studio Flamingo, the Kotlin plugin 1.8.0 is bundled into the latest Canary. For Android Studio Electric Eel, the IDE plugin will be delivered with the upcoming Android Studio updates.

If you need the command-line compiler, download it from the GitHub release page.

If you run into any problems

Stay up to date with the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form to the right of this post.

What else to read and watch

Top issue reporters from YouTrack 

Adam (7 issues), pyos (5 issues), Ting-Yuan Huang (5 issues), Jinseong Jeon (4 issues), Efeturi Money (3 issues), Anton Keks (3 issues), wrongwrong (3 issues), Michael Bailey (3 issues), Guozheng Yuan (2 issues), jimgoog (2 issues), Nikita Nazarov (2 issues), Troels Lund (2 issues), liutikas (2 issues), Artyom Krivolapov (2 issues), Steven Schäfer (2 issues), Фагим Садыков (2 issues), David Corrado (2 issues), Jørgen Svennevik Notland (2 issues), David Herman (2 issues), Cev Ing (2 issues).

External contributors

We’d like to thank all of our contributors whose pull requests were included in this release: Jinseong JeonpyosHung NguyenMads AgerKristoffer AndersenSteven SchäferRick ClephasTroels Bjerre LundTianyu GengIven KrallJaebaek SeoJerome PrinetJiaxiang ChenAnže SodjaAurimasIvan GavrilovicJohan BayMartynas PetuškaXin WangmcpiromanAhmed El-Helw, Aleksandr Kutashov, Aurimas LiutikasDiego Gomez OlveraJason ParachoniakJohan BayKevin BierhoffMartin BonninMatthew HaughtonRomain GuyShumaf LovpacheToshiaki KameyamaZac SweersaSemybennyhuosoarex.

Special thanks to our EAP Champions

They reported issues and helped us stabilize the Kotlin 1.8.0 release:

Continue ReadingKotlin 1.8.0 Released

Kotlin 1.7.20 Released

The Kotlin 1.7.20 release is out! Here are some highlights from this release:

For the complete list of changes, refer to What’s new in Kotlin 1.7.20 or release notes on GitHub.

How to install Kotlin 1.7.20

If you already use IntelliJ IDEA 213, 221, or 222, the IDE will suggest updating Kotlin to 1.7.20 automatically. You can also update manually by following these instructions.

For Android Studio Dolphin (213), Electric Eel (221), and Flamingo (222), the Kotlin plugin 1.7.20 will be delivered with upcoming Android Studios updates.

If you need the command-line compiler, download it from the GitHub release page.

If you run into any problems

Stay up to date with the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form to the right of this post.

What else to read and watch

Continue ReadingKotlin 1.7.20 Released

Kotlin 1.7.0 Released

Kotlin 1.7.0 has been released. It unveils the Alpha version of the new Kotlin/JVM K2 compiler, stabilizes language features, and brings performance improvements for the JVM, JS, and Native platforms.

Here is a list of the major updates in this version:

Read the complete list of changes in What’s new in Kotlin 1.7.0.


How to install Kotlin 1.7.0

If you already use IntelliJ IDEA or Android Studio Chipmunk (212), your IDE will suggest updating Kotlin to 1.7.0 automatically. You can also update manually for these IDEs by following these instructions.

For Intellij IDEA 2022.2, and Android Studio Dolphin (213) or Android Studio Electric Eel (221), the Kotlin plugin 1.7.0 will be delivered with upcoming Intellij IDEA and Android Studios updates.

Make sure that you have also updated the kotlinx libraries to compatible versions and specified version 1.7.0 of Kotlin in the build scripts of your existing projects.

If you need the command-line compiler, download it from the GitHub release page.

If you run into any problems

Stay up to date with the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form to the right of this post.

What else to read and watch

Top issue reporters from YouTrack 

Philip Wedemann (28 issues), AndroidDeveloperLB (20 issues), Morgan Bartholomew (12 issues), meng wang (10 issues), Carlos Ballesteros Velasco (10 issues), Ivan Gavrilovic (9 issues), Steven Schäfer (9 issues), Tianyi Guan (9 issues), Niklas Baudy (9 issues), holger brandl (9 issues), Mike Hearn (8 issues), Eliezer Graber (8 issues), Waldemar Kornewald (8 issues), Piotr Krzemiński (8 issues), Yigit Boyar (7 issues), Javier Segovia Córdoba (7 issues), Oliver O. (7 issues), vivek modi (7 issues), Philip Dukhov (7 issues).

External contributors

We’d like to thank all of our contributors whose pull requests were included in this release: Jinseong Jeon, Tianyu Geng, pyos, Hung Nguyen, Mark Punzalan, Mads Ager, Steven Schäfer, Irene Dea, Ivan Gavrilovic, Xin Wang, Kristoffer Andersen, wrongwrong, Mattia Iavarone, Martin Petrov, Aurimas, Alexey Subach, Udi Cohen, Quantum64, Dario Seidl, David Saff, Denis Mekhanikov, Egor, Glen K. Peterson, Ian Lynagh, Iaroslav Postovalov, Jerome Prinet, Jiaxiang Chen, Joseph Walton, Kevin Bierhoff, Matthew Haughton, Michael Rittmeister, Morten Krogh-Jespersen, Nikolay Kasyanov, Piotr Krzeminski, 770grappenmaker, Rick Clephas, Ryan Nett, Shumaf Lovpache, Starlight220, Yigit Boyar, Zac Sweers, aragos, baratynskiy, ov7a, sgmoore, soywiz, tdn120.

Continue ReadingKotlin 1.7.0 Released

Kotlin 1.7.0-Beta Released

The first preview of the 1.7.0 release is out. Introducing Kotlin 1.7.0-Beta! This preview includes:

  • Changes to builder inference.
  • The return of the min() and max() collection functions.
  • Stabilizing of definitely non-nullable types.
  • Updates for the new Kotlin/Native Memory Manager.

Install 1.7.0-Beta to try out these features and report any issues you find to help us improve Kotlin 1.7.0.

Install Kotlin 1.7.0-Beta

Starting from 1.7.0, we’re updating our cadence terminology by changing “Milestone” to “Beta”. There are few reasons behind this decision:

  • We want the Kotlin builds terminology to be more aligned with the standard terminology of the software release cycle. To put it more precisely, “Beta” means we’re done adding new features to that specific version and are working on stabilization. Though the final changes will be implemented, including changes based on your feedback.
  • Some time ago, M-release compilers were producing “pre-release” code, which made these versions harder to test. This is no longer the case. We want to avoid any confusion and emphasize that trying out Kotlin Beta versions is a simple process and highly encouraged by the Kotlin team. 
  • Last but not least, the term “Beta” itself is a call for feedback from the community. We use it to let you know we want you to share feedback with us.

Please evaluate Kotlin 1.7.0-Beta and share your feedback with us on YouTrack and Slack (for new Slack members: apply to be invited).

Changes to builder inference

Builder inference is a special kind of type inference that is useful when calling generic builder functions. It helps the compiler infer the type arguments of a call using the type information about other calls inside its lambda argument.

Kotlin 1.7.0-Beta includes further changes to builder inference. It brings us closer to builder inference stabilization and completion of one of the items on our roadmap.

With this release, builder inference is automatically activated if a regular type inference cannot get enough information about a type without specifying the -Xenable-builder-inference compiler option, which we introduced in version 1.6.0.

This means that now you can write your own builders that use builder type inference without applying any additional annotations or options. Learn how to write custom generic builders.

The return of the min() and max() collection functions

In Kotlin 1.4, we renamed the min() and max() collection functions to minOrNull() and maxOrNull(). These new names better reflect their behavior – returning null if the receiver collection is empty. It also helped to align the functions’ behavior with naming conventions used throughout the Kotlin collections API.

The same was true of minBy(), maxBy(), minWith(), and maxWith(), which all got their *OrNull() synonyms in Kotlin 1.4. Older functions affected by this change were gradually deprecated.

Kotlin 1.7.0-Beta reintroduces the original function names, but with a non-nullable return type. The renewed min(), max(), minBy(), maxBy(), minWith(), and maxWith() now strictly return the collection element or throw an exception.

fun main() {
    val numbers = listOf<Int>()
    println(numbers.maxOrNull()) // "null"
    println(numbers.max()) // "Exception in… Collection is empty."
}

See this YouTrack issue for details.

Stabilizing of definitely non-nullable types

Kotlin 1.7.0 will have stable definitely non-nullable types, which were introduced in Kotlin 1.6.20.

These types have been added to provide better interoperability when extending generic Java classes and interfaces.

Since Kotlin 1.6.20, you’ve been able to mark a generic type parameter as definitely non-nullable on the use site with the new syntax T & Any. The syntactic form comes from a notation of intersection types and is now limited to a type parameter with nullable upper bounds on the left side of & and non-nullable Any on the right side:

fun <T> elvisLike(x: T, y: T & Any): T & Any = x ?: y

fun main() {
    elvisLike<String>("", "").length // OK
    elvisLike<String>("", null).length // Error: 'null' cannot be a value of a non-null type

    elvisLike<String?>(null, "").length // OK
    elvisLike<String?>(null, null).length // Error: 'null' cannot be a value of a non-null type
}

Definitely non-nullable types are enabled by default in this Beta release. No additional steps are required.

Learn more about definitely non-nullable types in the KEEP.

Matching with Regex at a particular position

The Regex.matchAt() and Regex.matchesAt() functions, introduced in 1.5.30, are now Stable. They provide a way to check whether a regular expression has an exact match at a particular position in a String or CharSequence.

  • matchesAt() checks for a match and returns a boolean result:
fun main(){
    val releaseText = "Kotlin 1.7.0 is on its way!"
    // regular expression: one digit, dot, one digit, dot, one or more digits
    val versionRegex = "\d[.]\d[.]\d+".toRegex()

    println(versionRegex.matchesAt(releaseText, 0)) // "false"
    println(versionRegex.matchesAt(releaseText, 7)) // "true"
}
  • matchAt() returns the match if it’s found, or null if it isn’t:
fun main(){
    val releaseText = "Kotlin 1.7.0 is on its way!"
    val versionRegex = "\d[.]\d[.]\d+".toRegex()

    println(versionRegex.matchAt(releaseText, 0)) // "null"
    println(versionRegex.matchAt(releaseText, 7)?.value) // "1.7.0"
}

We’d be grateful for your feedback in this YouTrack issue.

Updates of new Kotlin/Native Memory Manager

You can try the Alpha version of the new Kotlin/Native memory manager in Kotlin 1.7.0-Beta. This EAP release brings performance improvements to the new memory manager that will improve the developer experience.

The new memory manager eliminates the differences between the JVM and Native platforms. It provides a consistent developer experience in multiplatform projects. For example, you’ll have a much easier time creating new cross-platform mobile applications that work on both Android and iOS.

The new Kotlin/Native memory manager lifts restrictions on object-sharing between threads. It also provides leak-free concurrent programming primitives that are safe and don’t require any special management or annotations.

The new memory manager will become the default one in future versions, so we encourage you to try it now. Learn more about the new memory manager and explore demo projects, or jump right to the migration instructions to try it yourself.

Try using the new memory manager on your projects to see how it works and share your feedback in our issue tracker, YouTrack.

Support for named capturing groups in JS and Native

Since Kotlin 1.7.0-Beta, named capturing groups are supported not only on the JVM (1.8 and later) but on JS and Native as well.

To give a name to a capturing group, use the (?<name>group) syntax in your regular expression. To get the text matched by a group, call the newly introduced MatchGroupCollection.get() function and pass the group name.

Retrieve matched group value by name

Consider this example for matching city coordinates. To get a collection of groups matched by the regular expression, use groups. Compare retrieving a group’s contents by its number (index) and by its name using value:

fun main() {
    val regex = "\b(?<city>[A-Za-z\s]+),\s(?<state>[A-Z]{2}):\s(?<areaCode>[0-9]{3})\b".toRegex()
    val input = "Coordinates: Austin, TX: 123"
 
    val match = regex.find(input)!!
    println(match.groups["city"]?.value) // "Austin" — by name
    println(match.groups[2]?.value) // "TX" — by number
}

Named backreferencing

You can now also use group names when backreferencing groups. Backreferences match the same text as previously matched by a capturing group. For this, use the k<name>  syntax in your regular expression:

fun backRef() {
    val regex = "(?<title>\w+), yes \k<title>".toRegex()
    val match = regex.find("Do you copy? Sir, yes Sir!")!!
    println(match.value) // "Sir, yes Sir"
    println(match.groups["title"]?.value) // "Sir"
}

Named groups in replacement expressions

Finally, named group references can be used with replacement expressions. Consider the replace() function that substitutes all occurrences of the regular expression in the input with a replacement expression, and the replaceFirst() function that swaps the first match only.

Occurrences of ${name} in the replacement string are substituted with the subsequences corresponding to the captured groups with the specified name. Compare replacements in group reference by name and by index:

fun dateReplace() {
    val dateRegex = Regex("(?<dd>\d{2})-(?<mm>\d{2})-(?<yyyy>\d{4})")
    val input = "Date of birth: 27-04-2022"
    println(dateRegex.replace(input, "${yyyy}-${mm}-${dd}")) // "Date of birth: 2022-04-27"  — by name
    println(dateRegex.replace(input, "$3-$2-$1")) // "Date of birth: 2022-04-27" — by number
}

Try new features and provide feedback 

These new features are available in the 1.7.0 preview release, Kotlin 1.7.0-Beta. You can easily install it in your IntelliJ IDEA or Android Studio IDE.

Due to Android Studios plugins renaming (Beta), plug-in installation is available on top of 1.6.20+ versions.

Install Kotlin 1.7.0-Beta in any of the following ways:

  • If you use the Early Access Preview update channel, the IDE will suggest automatically updating to 1.7.0-Beta as soon as it becomes available.
  • If you use the Stable update channel, you can change the channel to Early Access Preview at any time by selecting Tools | Kotlin | Configure Kotlin Plugin Updates in your IDE. You’ll then be able to install the latest preview release. Check out these instructions for details.

You can always download the latest versions of these IDEs to get extensive support for Kotlin:

  • IntelliJ IDEA for developing Kotlin applications for a variety of platforms.
  • Android Studio for developing Android and cross-platform mobile applications.

Once you’ve installed 1.7.0-Beta, don’t forget to change the Kotlin version to 1.7.0-Beta in your build scripts.

If you run into any problems:

Read more

Continue ReadingKotlin 1.7.0-Beta Released

Kotlin 1.6.20 Is Released

Kotlin 1.6.20 has officially been released. It offers previews of future language features, makes the hierarchical structure the default for multiplatform projects, and brings performance improvements for the JVM, JS, and Native platforms.

In this blog post, you’ll find an overview of the following improvements, along with a complete list of the other evolutionary changes:

How to update

If you use IntelliJ IDEA or Android Studio, you have the option to automatically update to the new Kotlin release as soon as it becomes available.

Update to Kotlin 1.6.20

Major updates

Prototype of context receivers for Kotlin/JVM

With Kotlin 1.6.20, you are no longer limited to having one receiver. If you need more, you can make functions, properties, and classes context-dependent (or contextual) by adding context receivers to their declaration. A contextual declaration does the following:

  • It requires all declared context receivers to be present in a caller’s scope as implicit receivers.
  • It brings declared context receivers into its body scope as implicit receivers.
interface LoggingContext {
    val log: Logger // This context provides a reference to a logger 
}

context(LoggingContext)
fun startBusinessOperation() {
    // You can access the log property since LoggingContext is an implicit receiver
    log.info("Operation has started")
}

fun test(loggingContext: LoggingContext) {
    with(loggingContext) {
        // You need to have LoggingContext in a scope as an implicit receiver
        // to call startBusinessOperation()
        startBusinessOperation()
    }
}

To enable context receivers in your project, use the -Xcontext-receivers compiler option. You can find a detailed description of the feature and its syntax in the KEEP.

Please note that the implementation is a prototype

  • With -Xcontext-receivers enabled, the compiler will produce pre-release binaries that cannot be used in production code. 
  • The IDE support for context receivers is minimal for now.

Definitely non-nullable types

To provide better interoperability when extending generic Java classes and interfaces, Kotlin 1.6.20 allows you to mark a generic type parameter as definitely non-nullable on the use site with the new syntax T & Any. The syntactic form comes from a notation of intersection types and is now limited to a type parameter with nullable upper bounds on the left side of & and non-nullable Any on the right side:

fun <T> elvisLike(x: T, y: T & Any): T & Any = x ?: y

fun main() {
   // OK
   elvisLike<String>("", "").length
   // Error: 'null' cannot be a value of a non-null type
   elvisLike<String>("", null).length

   // OK
   elvisLike<String?>(null, "").length
   // Error: 'null' cannot be a value of a non-null type
   elvisLike<String?>(null, null).length
}

Set the language version to 1.7 to enable the feature:

kotlin {
   sourceSets.all {
       languageSettings.apply {
           languageVersion = "1.7"
       }
   }
}

Learn more about definitely non-nullable types in the KEEP.

Please note that definitely non-nullable types are in Beta. They are almost stable, but migration steps may be required in the future. We’ll do our best to minimize any changes you have to make.

Support for parallel compilation of a single module in the JVM backend

In Kotlin 1.6.20, we added the experimental JVM IR backend mode to compile all the files in a module in parallel. Parallel compilation can reduce the total compilation time by up to 15%.

Enable the experimental parallel backend mode with the compiler option -Xbackend-threads. Use the following arguments for this option:

  • N is equal to the number of threads you want to use. It should not be greater than your number of CPU cores; otherwise, parallelization stops being effective because of switching context between threads
  • 0 to use one thread for each CPU core

Gradle can run tasks in parallel, but this type of parallelization doesn’t help a lot when a project (or a major part of a project) is just one big task from Gradle’s perspective. If you have a very big monolithic module, use parallel compilation to compile more quickly. If your project consists of lots of small modules and has a build parallelized by Gradle, adding another layer of parallelization may hurt performance because of context switching.

Parallel compilation has some constraints:

  • It doesn’t work with kapt because kapt disables the IR backend.
  • It requires more JVM heap by design. The amount of heap is proportional to the number of threads.

Incremental compilation for development binaries with Kotlin/JS IR compiler

To make Kotlin/JS development with the IR compiler more efficient, we’re introducing a new incremental compilation mode.

When building development binaries with the compileDevelopmentExecutableKotlinJs Gradle task in this mode, the compiler caches the results of previous compilations on the module level. It uses the cached compilation results for unchanged source files during subsequent compilations, making them complete more quickly, especially with small changes. Note that this improvement exclusively targets the development process (shortening the edit-build-debug cycle) and doesn’t affect the building of production artifacts.

To enable incremental compilation for development binaries, add the following line to the project’s gradle.properties:

kotlin.incremental.js.ir=true // false by default

In our test projects, the new mode made incremental compilation up to 30% faster. However, the clean build in this mode became slower because of the need to create and populate the caches.

Kotlin/Native performance improvements

Kotlin 1.6.20 brings some performance updates and bug fixes that affect the LLVM IR that Kotlin generates. According to the benchmarks on our internal projects, we achieved the following performance boosts on average:

  • 15% reduction in execution time
  • 20% reduction in the code size of both release and debug binaries
  • 26% reduction in the compilation time of release binaries

These changes also provide a 10% reduction in compilation time for a debug binary on a large internal project.

To achieve this, we’ve implemented static initialization for some of the compiler-generated synthetic objects, improved the way we structure LLVM IR for every function, and optimized the compiler caches.

Hierarchical structure support for multiplatform projects

Kotlin 1.4.0, we’ve significantly improved the frontend and made IDE import stable.

Previously, there were two ways to add code in a multiplatform project. The first was to insert it in a platform-specific source set, which is limited to one target and can’t be reused by other platforms. The second is to use a common source set shared across all the platforms that are currently supported by Kotlin.

Now you can share source code among several similar native targets that reuse a lot of the common logic and third-party APIs. The technology will provide the correct default dependencies and find the exact API available in the shared code. This eliminates a complex build setup and having to use workarounds to get IDE support for sharing source sets among native targets. It also helps prevent unsafe API usages meant for a different target.

The technology will come in handy for library authors too, as a hierarchical project structure allows them to publish and consume libraries with common APIs for a subset of targets.
By default, libraries published with the hierarchical project structure are compatible only with hierarchical structure projects. Learn more about project-library compatibility.

Better code-sharing in your project

Without hierarchical structure support, there is no straightforward way to share code across some but not all Kotlin targets. One popular example is sharing code across all iOS targets and having access to iOS-specific dependencies, like Foundation.

Thanks to the hierarchical project structure support, you can now achieve this out of the box. In the new structure, source sets form a hierarchy. You can use platform-specific language features and dependencies available for each target that a given source set compiles to.

For example, consider a typical multiplatform project with two targets — iosArm64 and iosX64 for iOS devices and simulators. The Kotlin tooling understands that both targets have the same function and allows you to access that function from the intermediate source set, iosMain.

The Kotlin toolchain provides the correct default dependencies, like Kotlin/Native stdlib or native libraries. Moreover, Kotlin tooling will try its best to find exactly the API surface area available in the shared code. This prevents such cases as, for example, the use of a macOS-specific function in code shared for Windows.

More opportunities for library authors

When a multiplatform library is published, the API of its intermediate source sets is now properly published alongside it, making it available for consumers. Again, the Kotlin toolchain will automatically figure out the API available in the consumer source set while carefully watching out for unsafe usages, like using an API meant for the JVM in JS code. Learn more about sharing code in libraries.

Configuration and setup

Starting with Kotlin 1.6.20, all your new multiplatform projects will have a hierarchical project structure. No additional setup is required.

  • If you’ve already turned it on manually, you can remove the deprecated options from gradle.properties:
kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.native.enableDependencyPropagation=true
  • For Kotlin 1.6.20, we recommend using Android Studio 2021.1.1 (Bumblebee) or later to get the best experience.
  • You can also opt out. To disable hierarchical structure support, set the following options in gradle.properties:
kotlin.mpp.hierarchicalStructureSupport=false

Complete list of improvements

Language

Kotlin/JVM

Kotlin/Native

Kotlin Multiplatform

Kotlin/JS

Security

Gradle

How to install Kotlin 1.6.20

If you already use IntelliJ IDEA or Android Studio, your IDE will suggest updating Kotlin to 1.6.20 automatically. You can also update manually by following these instructions

You can download the latest versions of these IDEs to get extensive support for Kotlin:

  • IntelliJ IDEA – for developing Kotlin applications for various platforms.
  • Android Studio –  for developing Android and cross-platform mobile applications.

Make sure that you have also updated the kotlinx libraries to compatible versions and specified version 1.6.20 of Kotlin in the build scripts of your existing projects.

If you need the command-line compiler, download it from the Github release page.

If you run into any problems

Stay up to date with the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form to the right of this post.

What else to read and watch

Continue ReadingKotlin 1.6.20 Is Released

Kotlin 1.6.0 veröffentlicht

Kotlin 1.6.0 ist jetzt offiziell veröffentlicht – mit Stable-Status für abschließende when-Blöcke, dem Code-Coverage-Tool Kover und einem neuen Speichermanager für Kotlin/Native. Auch andere Neuerungen in der Sprache und den Standardbibliotheken, die in 1.5.30 veröffentlicht wurden, wurden in den Status Stable befördert. Vielen Dank für das Feedback, das Sie uns zukommen ließen. Wenn Sie diese neuen Features noch nicht ausprobiert haben – jetzt ist es höchste Zeit!

In diesem Blogbeitrag finden Sie einen Überblick über die folgenden Updates:

  • Neue Sprachmerkmale: versiegelte when-Anweisungen, suspendierende Funktionen und entsprechende Umwandlungen, Instanziierung von Annotationsklassen, verbesserte Typinferenz für reguläre und Builder-Typen.
  • Kotlin/JVM mit optimierten delegierten Eigenschaften und wiederholbaren Annotationen.
  • Kotlin/Native mit der Preview eines neuen Speichermodells, Xcode-13-Unterstützung, Kreuzkompilierung von Windows-Zielen, LLVM- und Linker-Updates, Leistungsupdates und einer einheitlichen Compiler-Plugin-ABI.
  • Optionale Deaktivierung des Herunterladens von Node.js und Yarn für Kotlin/JS.
  • Ankündigung von Kover.
  • Standardbibliothek mit neuen Funktionen für die Standardeingabe, stabiler typeOf()-Funktion, stabiler Duration-API und weiteren stabilen stdlib-Funktionen.

Abonnieren Sie unser Blog, um keine Kotlin-Updates zu verpassen!

So führen Sie das Update durch

Wenn Sie IntelliJ IDEA oder Android Studio verwenden, haben Sie die Möglichkeit, automatisch auf die neue Kotlin-Version zu aktualisieren.

Weitere Informationen zur Installation von Kotlin 1.6.0.

Auf Kotlin 1.6.0 aktualisieren

Sprachmerkmale

Wir haben Sprachmerkmale aus Kotlin 1.5.30 basierend auf Ihrem Feedback stabilisiert.

Abschließende (versiegelte) when-Anweisungen

Versiegeltes when ist eine lang erwartete Funktion des Kotlin-Compilers, die Sie warnt, wenn Ihre when-Anweisungen nicht abschließend sind, also nicht alle Möglichkeiten berücksichtigen. Dadurch wird Ihr Code sicherer, ohne eigene Funktionen für diesen Zweck schreiben zu müssen. 

Kotlin hat when-Ausdrücke, die sich auf versiegelte Klassen, Enums und boolesche Typen bezogen, schon immer auf Vollständigkeit überprüft. Dies ist nützlich, wenn Sie Ihre Domäne mit diesen algebraischen Datentypen abbilden. Sie könnten beispielsweise in Ihrer App unterschiedliche Kontaktpräferenzen der Benutzer*innen als versiegelte Klassenhierarchie modellieren:

sealed class Contact {
   data class PhoneCall(val number: String) : Contact()
   data class TextMessage(val number: String) : Contact()
   data class InstantMessage(val type: IMType, val user: String) : Contact()
}

Wenn Sie nun einen Ausdruck schreiben, der abhängig von der Kontakteinstellung ein unterschiedliches Ergebnis zurückgibt, meldet der Compiler einen Fehler, wenn Sie vergessen haben, alle Typen zu berücksichtigen, die in Ihrer App möglich sind:

fun Rates.computeMessageCost(contact: Contact): Cost =
   when (contact) { // ERROR: 'when' expression must be exhaustive
       is Contact.PhoneCall -> phoneCallCost
       is Contact.TextMessage -> textMessageCost
   }

Dies ist eine große Hilfe sowohl beim Schreiben des Codes als auch bei der späteren Wartung. Wenn Sie später eine weitere Kontaktoption hinzufügen, können Sie sich darauf verlassen, dass der Compiler Sie daran erinnert, die verschiedenen Kontaktpräferenzen überall in Ihrem Code zu berücksichtigen.

Vor Kotlin 1.6 wurde jedoch die when-Anweisung im folgenden Code erfolgreich kompiliert, obwohl versäumt wurde, den Versand einer Nachricht per Instant Messaging zu implementieren:

fun sendAnnouncement(contact: Contact, announcement: Announcement) {
   when (contact) {
       is Contact.PhoneCall -> schedulePhoneCall(contact.number, announcement)
       is Contact.TextMessage -> sendTextMessage(contact.number, announcement)
   }
}

Das Problem wurde nur von einer nachrangigen IDE-Inspektion gemeldet, ohne irgendwelche Meldungen vom Compiler. Ab Kotlin 1.6 wird die folgende Compiler-Warnung ausgegeben:

Non-exhaustive 'when' statements on sealed class/interface will be prohibited in 1.7. Add an 'is InstantMessage' branch or 'else' branch instead.

In Kotlin 1.7 wird dies als Fehler gewertet, damit solche Fälle nicht übersehen werden können. Im Ticket KT-47709 finden Sie eine genauere Erläuterung der Änderung und ihrer Auswirkungen. 

Suspendierende Funktionen als Supertypen

Kotlin 1.6 stabilisiert die Unterstützung für die Implementierung von suspend-Funktionstypen als Superschnittstellen. Dies war eines der fehlenden Puzzleteile beim Design der Kotlin-Coroutinen. 

Bei der Gestaltung von Kotlin-APIs ist es idiomatisch, Funktionstypen zu akzeptieren, wenn das Verhalten von Bibliotheksfunktionen anpassbar sein soll. Beispielsweise verfügt die Schnittstelle Job der API kotlinx.coroutines über eine Memberfunktion, die ungefähr so aussieht:

fun invokeOnCompletion(handler: () -> Unit)

Sie können diese Funktion bequem mit Lambdas wie nachAbschlussAufrufen { etwasTun() } verwenden. Wenn Sie eine Klasse haben, die auf den Abschluss reagieren soll, können Sie Ihren Code vereinfachen und optimieren, indem Sie den Funktionstyp () -> Unit direkt in Ihrer Klasse implementieren, sodass Sie keine zusätzliche Lambdafunktion benötigen:

class MyCompletionHandler : () -> Unit {
   override fun invoke() { doSomething() }
}

Ab Kotlin 1.6 ist diese Optimierung mit suspendierenden Funktionen möglich. Nehmen wir an, Ihre API akzeptiert suspendierende Funktionstypen wie diese:

public fun launchOnClick(action: suspend () -> Unit) {}

In diesem Fall sind Sie nicht mehr darauf beschränkt, Lambdas und Referenzen auf suspendierende Funktionen an diesen Code zu übergeben. Sie können die entsprechenden suspendierenden Funktionstypen auch in einer Klasse implementieren:

class MyClickAction : suspend () -> Unit {
   override suspend fun invoke() { doSomething() }
}

Umwandlungen in suspendierende Typen

Kotlin 1.6 befördert die Umwandlungen von regulären zu suspendierenden Funktionstypen in den stabilen Status. Wenn bei einem Parameter ein suspendierender Typ erwartet wird, können Sie jetzt einen geeigneten regulären Funktionstyp übergeben. Der Compiler führt die Umwandlung automatisch durch.

Dadurch wird eine kleine, aber störende Inkonsistenz beim Zusammenspiel zwischen regulären und suspendierenden Funktionen in Kotlin behoben. Wenn Sie eine Funktion höherer Ordnung haben, die eine suspendierende Funktion akzeptiert (Beispiel: ein collect-Aufruf auf einem Kotlin-Flow), müssen Sie zum Aufrufen nicht unbedingt ein Lambda wie im folgenden Code verwenden:

flow.collect { processItem(it) }
fun processItem(item: Item) { /* ... */ }

Stattdessen könnte es praktischer sein, eine Referenz auf die Funktion processItem an den collect-Aufruf zu übergeben – die Wirkung ist identisch.

flow.collect(::processItem)

Sie könnten dann eine Referenz auf Ihre Verarbeitungsfunktion in eine Variable extrahieren, um das Verhalten in Ihrem Code entsprechend anzupassen. Allerdings funktionierte dies in den Kotlin-Versionen vor 1.6 nicht. Dies liegt daran, dass Sie eine reguläre Funktion als Parameter übergeben, wo ein suspendierender Typ erwartet wird:

val processingFunction = ::processItem
flow.collect(processingFunction) // ERROR: Type mismatch

Der obige Code wird in Kotlin 1.6 einwandfrei kompiliert und funktioniert auch wie erwartet.

Verbesserte Typinferenz für rekursive generische Typen

Ab 1.6.0 kann der Kotlin-Compiler standardmäßig ein Typargument basierend nur auf den oberen Grenzen des entsprechenden Typparameters ableiten, wenn dieser ein rekursiver generischer Typ ist. Dies ermöglicht verschiedene Patterns mit rekursiven generischen Typen, die in Java häufig für Builder-APIs verwendet werden.

// Vor 1.5.30
val containerA = PostgreSQLContainer<nothing>(DockerImageName.parse("postgres:13-alpine")).apply {
    withDatabaseName("db")
    withUsername("user")
    withPassword("password")
    withInitScript("sql/schema.sql")
}

// Mit Compileroption in 1.5.30 oder standardmäßig ab 1.6.0
val containerB = PostgreSQLContainer(DockerImageName.parse("postgres:13-alpine"))
    .withDatabaseName("db")
    .withUsername("user")
    .withPassword("password")
    .withInitScript("sql/schema.sql")

Verbesserte Builder-Inferenz

In Kotlin 1.5.30 wurde die Compileroption -Xunrestricted-builder-inference eingeführt, um innerhalb von Builder-Lambdas auf Typinformationen über einen Builder-Aufruf zugreifen zu können. Konkret bedeutet dies die Möglichkeit, Aufrufe zu tätigen, die eine Instanz eines noch nicht bekannten Typs zurückgeben, z. B. get() in einem buildList()-Lambda.

Ab 1.6.0 müssen Sie nicht die Option -Xunrestricted-builder-inference angeben, um diese bisher unzulässigen Aufrufe zu tätigen. Mit der Compileroption -Xenable-builder-inference können Sie jetzt ohne Verwendung der Annotation @BuilderInference Ihre eigenen generischen Builder schreiben und Builder-Inferenzen automatisch aktivieren, wenn die reguläre Typinferenz keine Typinformationen ergibt.

Längere Unterstützung früherer API-Versionen

Ab Kotlin 1.6.0 können Sie bei der Entwicklung außer der aktuellen stabilen API-Version drei frühere Versionen (anstelle der bisherigen zwei) verwenden. Derzeit stehen Ihnen also die API-Versionen 1.3, 1.4, 1.5 und 1.6 zur Verfügung.

Kotlin/JVM

Wiederholbare Annotationen mit Laufzeiterhaltung. Wie Java 8 kennt auch Kotlin wiederholbare Annotationen. Ab Kotlin 1.6 ist diese Funktion Java-kompatibel. @kotlin.annotation.Repeatable akzeptiert jetzt jede Retention-Angabe und macht die Annotation sowohl in Kotlin als auch in Java wiederholbar. Außerdem werden wiederholbare Java-Annotationen jetzt auch auf Kotlin-Seite unterstützt.

Kotlin/Native

Ab sofort können Sie die experimentelle Version des neuen Kotlin/Native-Speichermanagers ausprobieren. Mit diesem Feature kommen wir unserem Ziel einer konsistenten Entwicklererfahrung bei Multiplattform-Projekten näher. Der neue Speichermanager hebt die bestehenden Beschränkungen für die gemeinsame Objektnutzung zwischen Threads auf und bietet Primitive für die nebenläufige Programmierung, die sicher sind, Lecks vermeiden und keine spezielle Verwaltung oder Annotationen von Seiten des Entwicklungsteams erfordern.

Sie können Xcode unbesorgt aktualisieren und an Ihren Kotlin-Projekten weiterarbeiten, da Kotlin/Native jetzt Xcode 13 unterstützt. 

Kompilieren von Windows-Zielen auf beliebigen Hosts. Sie können die Windows-Ziele mingwX64 und mingwX86 auf jedem Host kompilieren, der Kotlin/Native unterstützt.

Wir haben die LLVM-Abhängigkeit, die Kotlin/Native unter der Haube verwendet, überarbeitet. Neben einer auf 11.1.0 aktualisierten LLVM-Version und einer verringerten Größe der Abhängigkeiten bietet dies einige weitere Vorteile.

Vereinheitlichung der Compiler-Plugin-ABI mit den JVM- und JS-IR-Backends. Jetzt kann das Gradle-Plugin für Kotlin Multiplatform das einbettbare Compiler-Jar, das für die JVM- und JS-IR-Backends verwendet wird, auch für Kotlin/Native verwenden. Sie können jetzt dieselben Compiler-Plugin-Artefakte für die Native-Plattform und andere unterstützte Plattformen verwenden.

Kotlin/JS

Für Buildvorgänge auf einem Server ohne Internetverbindung können Sie jetzt das Herunterladen von Node.js und Yarn für Kotlin/JS-Projekte deaktivieren und die auf dem Host vorinstallierten Instanzen verwenden.

Kover

Die genaue Ermittlung der Code-Coverage war vom ersten Kotlin-Release an eine Herausforderung. Einige großartige Tools wie JaCoCo verarbeiten Kotlin-Code, sind jedoch nicht vollständig in unsere Gradle-Toolchain und unsere Multiplattform-Projekte integriert. In dieser Kotlin-Version haben wir begonnen, dieses Problem anzupacken. Unser neues Gradle-Plugin Kover ermittelt die Code-Coverage von Kotlin-Code, der mit dem Kotlin/JVM-Compiler kompiliert wurde. Das Tool befindet es sich in einer frühen Entwicklungsphase und gilt als experimentell – wir freuen uns auf Ihr Feedback in GitHub.

Sehen Sie sich das Kover-Video an, um mehr zu erfahren.

Standardbibliothek

Kotlin 1.6.0 schließt drei Einträge auf der stdlib-Roadmap: kein !! nach readLine(), stabiler Status für typeOf() und eine stabile Duration-API. Außerdem erhalten die folgenden stdlib-Elemente den Status Stable:

  • Collection-Builder
  • Bit-Rotation bei Ganzzahlen
  • Regex-Funktion zum Aufteilen von Zeichenfolgen in Sequenzen

Außerdem können Sie jetzt compareTo mit Infixnotation verwenden, und wir haben an der Konsistenz zwischen den replace()-Funktionen in JVM und JS gearbeitet.

Neue Funktionen für die Standardeingabe

In Kotlin 1.6.0 ist der Nicht-Null-Assertion-Operator !! nach dem Lesen einer Zeile von der Standardeingabe nicht mehr erforderlich. Dies vereinfacht den Einstieg für Neulinge und erleichtert das Unterrichten von Kotlin.

Wir bieten die folgenden neuen Möglichkeiten für das Lesen von der Konsole:

  • readln() löst eine Ausnahme aus, wenn das Dateiende erreicht wurde. Sie können diese Funktion verwenden, statt das Ergebnis von readLine() mit dem Operator !! auf null zu überprüfen.
  • Die neue Funktion readlnOrNull() ist eine Alternative, die null zurückgibt. Sie verhält sich also wie bisher readLine() – nur dass die Funktion jetzt einen passenderen Namen hat.

Diese Funktionen sind für JVM und Native verfügbar. Sie sind analog zu println() benannt – für Neueinsteiger*innen ist dies besonders hilfreich.

fun main() {
    println("Input two integer numbers each on a separate line")
    val num1 = readln().toInt()
    val num2 = readln().toInt()
    println("The sum of $num1 and $num2 is ${num1 + num2}")
}

Stabile Duration-API

Mithilfe Ihres Feedbacks haben wir die API für Zeiträume stabilisiert und den entsprechenden Roadmap-Eintrag geschlossen.

Neben einer besser lesbaren Ausgabe von Duration.toString() und neuen Funktionen zum Parsen von Durations aus Strings, die in 1.5.30 als Preview verfügbar waren, hat die Duration-API folgende Änderungen erfahren:

  • Die days-Komponente der Funktion toComponents ist jetzt vom Typ Long statt Int, um das Abschneiden von Werten zu vermeiden.
  • Die Enum DurationUnit ist kein Typalias mehr. Es gibt keine Fälle, in denen es als Typalias für Java.util.concurrent.TimeUnit in der JVM verwendet wird.
  • Als Wunsch der Community sind Erweiterungseigenschaften wie Int.seconds wieder da. Um ihre Anwendbarkeit einzuschränken, sind sie nur im Companion-Objekt der Klasse Duration verfügbar.
import kotlin.time.Duration.Companion.seconds

fun main() {
//sampleStart
    val duration = 5000.seconds
    println("There are ${duration.inWholeMinutes} minutes in ${duration.inWholeHours} hours")
//sampleEnd
}

Stabiles typeOf()

In Kotlin 1.6.0 hat typeOf() den Status Stable. Der entsprechende Roadmap-Eintrag wurde geschlossen. Seit 1.3.40 war typeOf() auf der JVM-Plattform als experimentelle API verfügbar. Jetzt ist die Funktion auf jeder Kotlin-Plattform verfügbar und gibt einen beliebigen Kotlin-Typ, den der Compiler ableiten kann, als KType zurück. 

inline fun <reified T> renderType(): String {
    val type = typeOf<T>()
    return type.toString()
}

fun main() {
    val fromExplicitType = typeOf<Int>()
    val fromReifiedType = renderType<List<Int>>()
}

Stabile Collection-Builder

Kotlin 1.6.0 befördert Collection-Builder-Funktionen wie buildMap(), buildList() und buildSet() in den Stable-Status. Von den Buildern zurückgegebene Collections sind jetzt im schreibgeschützten Zustand serialisierbar.

Stabile Bitrotation für Ganzzahlen

Die Funktionen rotateLeft() und rotateRight(), die die binäre Darstellung einer Zahl um die angegebene Anzahl von Bits nach links oder rechts rotieren, haben ab Kotlin 1.6.0 den Status Stable.

fun main() {
//sampleStart
    val number: Short = 0b10001
    println(number.rotateRight(2).toString(radix = 2)) // 100000000000100
    println(number.rotateLeft(2).toString(radix = 2))  // 1000100
//sampleEnd
}

Stabile Regex-Funktion zum Aufteilen von Zeichenfolgen in Sequenzen

Eine weitere seit Kotlin 1.6.0 stabile Funktion ist splitToSequence() zum Aufteilen einer Zeichenfolge in eine Sequenz mithilfe eines regulären Ausdrucks.

fun main(){
//sampleStart
    val colorsText = "green, red , brown&blue, orange, pink&green"
    val regex = "[,\s]+".toRegex()
    val mixedColor = regex.splitToSequence(colorsText)
        .onEach { println(it) }
        .firstOrNull { it.contains('&') }
    println(mixedColor) // "brown&blue"
//sampleEnd
}

CompareTo in Infixnotation

Die Funktion Comparable.compareTo zum Vergleichen von zwei Objekten kann jetzt in Infixnotation aufgerufen werden: 

class WrappedText(val text: String) : Comparable<WrappedText> {
    override fun compareTo(other: WrappedText): Int =
        this.text compareTo other.text
}

Einheitlichkeit zwischen JVM und JS bei replace() und replaceFirst()

Vor Kotlin 1.6.0 verhielten sich die Regex-Funktionen replace() und replaceFirst() auf JVM und JS unterschiedlich, wenn die Ersetzungszeichenfolge eine Gruppenreferenz enthielt. Das Verhalten von Kotlin/JS wurde an das Verhalten der JVM angepasst.

Kompatibilität

Wie bei allen Feature-Releases werden mit Kotlin 1.6.0 einige Deprecation-Zyklen für zuvor angekündigte Änderungen abgeschlossen. Alle diese Fälle wurden vom Sprachkomitee sorgfältig geprüft und sind im Kompatibilitätsleitfaden für Kotlin 1.6 aufgeführt. Sie können diese Änderungen auch in YouTrack einsehen.

Installation von Kotlin 1.6.0

Wenn Sie IntelliJ IDEA oder Android Studio verwenden, schlägt Ihnen die IDE automatisch die Aktualisierung auf Kotlin 1.6.0 vor. Alternativ ist auch eine manuelle Aktualisierung gemäß dieser Anleitung möglich.

Sie können die neuesten Versionen dieser IDEs herunterladen, um eine umfassende Kotlin-Unterstützung zu erhalten:

  • IntelliJ IDEA – zur Entwicklung von Kotlin-Anwendungen für verschiedene Plattformen.
  • Android Studio – zur Entwicklung von Android-Apps und plattformübergreifenden Mobilanwendungen.

Achten Sie darauf, auch die kotlinx-Bibliotheken auf die kompatiblen Versionen zu aktualisieren und die Kotlin-Version 1.6.0 in den Build-Skripten Ihrer bestehenden Projekte anzugeben.

Den Befehlszeilen-Compiler können Sie bei Bedarf von der GitHub-Release-Seite herunterladen.

Hilfe bei Problemen:

Bleiben Sie stets auf dem neuesten Stand der Kotlin-Entwicklung! Abonnieren Sie unsere Kotlin-Updates, indem Sie das Formular rechts neben diesem Beitrag ausfüllen.

Weitere Informationen zum Lesen und Ansehen

Liste der aktivsten Ticketersteller in YouTrack 

Ryan Nett (48 Tickets), Zac Sweers (22 Tickets), Tianyu Geng (18 Tickets), zhelenskiy (18 Tickets), Thodoris Sotiropoulos (15 Tickets), AndroidDeveloperLB (14 Tickets), Morgan, Bartholomew (14 Tickets), Mikhail Naftal (14 Tickets), Louis CAD (12 Tickets), Philip Wedemann (12 Tickets), Victor Turansky (11 Tickets), Igor Wojda (11 Tickets), Martin Bonnin (11 Tickets), Iaroslav Postovalov (11 Tickets), Cedric (10 Tickets), (9 Tickets), Ben Woodworth (8 Tickets), Tianyi Guan (8 Tickets), Chris Povirk (8 Tickets), Alon Albert (8 Tickets).

Externe Mitwirkende

Wir bedanken uns bei allen Mitwirkenden, die Pull-Requests zu dieser Version beigetragen haben: Pyos, Tianyu Geng, Jinseong Jeon, Steven Schäfer, Mark Punzalan, Hung Nguyen, Mads Ager, Ting-Yuan Huang, Matthew Gharrity, Ivan Gavrilovic, Xin Wang, ov7a, Jiaxiang Chen, Yigit Boyar, Bingran, bracadabra, Steffi Stumpos, Andrey Kuleshov.

Autorin des Original-Blogposts:

Sergiy Rogalin

Alina Grebenkina

Continue ReadingKotlin 1.6.0 veröffentlicht

Improved IDE Performance, New Editor Inline Hints, and More for Kotlin in the Latest IntelliJ IDEA

Enjoy a better debugging experience, improved IDE performance, new editor inline hints for ranges and chain calls, and more improvements for Kotlin in IntelliJ IDEA 2021.3:

Auto-update to this new release

IntelliJ IDEA will give you the option to automatically update to the new release as soon as it is available.

If you are not yet an IntelliJ IDEA user, you can download the latest version here.

Better debugger experience

IntelliJ IDEA 2021.3 brings an improved debugger that works better with inline functions, has a smarter Step Into action, and works faster with coroutines.

Inline stack frames

The debugger can now detect Kotlin inline functions and show inline function calls in the stack trace panel. You can navigate to these calls and inspect and evaluate the variables of each frame.

Smart Step Into

The latest IntelliJ IDEA comes with the new Smart Step into action, which makes the debugging process more predictable. It allows you to stop at any child function when one line of Kotlin code calls several methods.

When you find yourself at a line with more than one method call, just click the Step Into button located in the top pane of the Debug tool window, or use the F7 shortcut. The IDE will then highlight the places where you can step into the code, and you’ll be able to select the line you want by clicking on it.

This feature is available by default. If you want to disable this default behavior for the Step Into action, go to Preferences / Settings | Build, Execution, Deployment | Debugger | Stepping | Kotlin and deselect the Always do smart step into checkbox. If you do so, the Smart Step Into action will still be available via the ⇧ F7 shortcut on macOS or Shift+F7 on Windows and Linux.

Coroutines debugger speed-up

The Coroutine debugger now calculates information about coroutines much faster. We did some research and found a way to optimize calls to JVM Debugger. Now the coroutine panel will load instantly, even if there are a lot of coroutines. Thanks to this change, it has become much more comfortable to use the coroutine debugger in sessions with a remote client.

Performance improvements

IntelliJ IDEA 2021.3 brings some major performance improvements for Kotlin. Besides a bunch of fixes for freezes and IDE slowdowns, it also comes with a compiler reference index, which significantly improves the speed of the “Find Usages” action and a built-in cache recovery troubleshooting tool designed to solve problems related to cache inconsistencies without requiring complete cache invalidation.

Compiler Reference Index

The new compiler index reference allows you to find declaration usages much faster. Using the information from the compiler, the search is performed only in files that actually use the declaration you are looking for, and not in all possible files. The more common the declaration name, the more effective the optimization is. The new compiler index reference also improves the search for declarations that have implicit calls (like Data Classes, as they generate `componentN` functions that are used in destructive declaration). Here’s an example of how this new feature improves the performance of “Find Usages” with and without a compiler index for an IntelliJ-community project on a Linux agent for different declarations:

The Compiler Reference Index feature is available for Maven and IntelliJ built-in build systems.

Cache recovery

Cache recovery is a useful built-in troubleshooting tool that has been introduced to solve problems related to cache inconsistencies without requiring complete cache invalidation when possible. The new Run Guided Cache Recovery… action offers two main advantages compared to Invalidate Caches: Run Guided Cache Recovery… : it can be performed per project, and it’s faster.

The action consists of a sequence of several actions, with the ability to stop after each of them. Each action will take less time than reindexing and will not lead to the loss of caches for other projects. The final action – Invalidate Caches and Restart – will reboot the IDE. After each action is performed, the user will be shown a notification with the option to abort the cache recovery process or perform the next step. The action can be invoked right from the main menu.

Editor inline hints

IntelliJ IDEA 2021.3 comes with new editor inline hints for ranges, chain calls, and VCS changes.

Inline hints for ranges

With the new IntelliJ IDEA it has become much easier to interpret range bounds, as it comes with new inline hints that explain with plain mathematical signs what the words or symbols used for the ranges mean:

This feature is enabled by default. If you want to switch it off, right-click on a hint and select Disable ‘Ranges’ hints type or go to Preferences / Settings | Editor | Inline hints | Kotlin | Ranges and deselect the Show ranges checkbox there.

Chain calls

IntelliJ IDEA 2021.3 displays type hints for long method chains. Previously, these hints were available only for Java, but now they work with Kotlin as well. It is especially useful to see the type of each call as a type hint for long method chains with generics. For simple builders where the type is obvious, the IDE will hide the type hint.

New refactorings and improved inspections and intentions

IntelliJ IDEA 2021.3 comes with a new extract constant refactoring, and Constant conditions inspection. It also brings an improved Possibly blocking call in non-blocking context inspection and improved intention preview.

Extract constant refactoring

A new refactoring allows you to extract constants in Kotlin. To use it, put the caret on a string and press ⌥⌘C on macOS or Ctrl+Alt+C on Windows and Linux.

Constant conditions inspection

With the help of new Constant conditions inspection, IntelliJ IDEA can report non-trivial conditions and values that are statically known to be always true, false, null, or zero. This inspection tracks and warns you about bugs that should be fixed and redundant code.

​​

You can find this inspection in Preferences / Settings | Editor | Inspections | Kotlin | Probable bugs.

Improved intention preview

IntelliJ IDEA 2021.3 comes with an improved intention preview. Now it:

  • works for more intention actions and quick-fixes in Kotlin.
  • displays informative HTML descriptions for intention actions which are impossible to show a preview for.
  • partially shows the possible outcomes for an action that modifies several files.

Improved Possibly blocking call in non-blocking context inspection

The Possibly blocking call in non-blocking context inspection warns you if you use a coroutine in the wrong context. The new IntelliJ IDEA comes with an improved version of this inspection that covers more cases so you can customize to work better in your particular environment. It is now possible for the inspection to prompt you about the problem and offer a context-dependent quick-fix.

More features

IntelliJ IDEA 2021.3 also brings more IDE features that improve the Kotlin experience. You can read more about them in the related IntelliJ IDEA EAP blog posts:

See also

  • What’s new in IntelliJ IDEA 2021.2 – docs
  • What’s new for Kotlin in IntelliJ IDEA 2021.2 – blog post
Continue ReadingImproved IDE Performance, New Editor Inline Hints, and More for Kotlin in the Latest IntelliJ IDEA

Kotlin 1.6.0 Released

Kotlin 1.6.0 is now officially released with Stable exhaustive whens, Kover, and a new memory manager for Kotlin/Native. Other language and standard library features released in 1.5.30 became Stable as well. Thanks for the feedback you’ve shared with us. If you still haven’t tried these new features out, now is the time!

In this blog post, you can find an overview of the following updates:

  • Language features with sealed when statements, suspending functions and suspend conversions, instantiation of annotation classes, improved regular type inference and builder type inference.
  • Kotlin/JVM with optimized delegated properties and repeatable annotations.
  • Kotlin/Native with a preview of a new memory model, Xcode 13 support, a cross-compilation of Windows targets, LLVM and linker updates, performance updates, and unified compiler plugin ABI.
  • Option to disable downloading of Node.js and Yarn for Kotlin/JS.
  • Kover announcement.
  • Standard library with new functions for standard input, Stable typeOf(), Stable Duration API, and other stabilized stdlib functions.

Subscribe to our blog and don’t miss out on any Kotlin updates

How to update

If you use IntelliJ IDEA or Android Studio, you have the option to automatically update to the new Kotlin release as soon as it becomes available.

Learn more about installing Kotlin 1.6.0.

Update to Kotlin 1.6.0

Language features

We stabilized features from Kotlin 1.5.30 based on your feedback.

Sealed (exhaustive) when statements

Sealed when is a long-awaited feature that makes the Kotlin compiler warn you if your when statements are not exhaustive. This makes your code safer without having to introduce your own functions. 

Kotlin has always been exhaustive in checking when expressions for sealed classes, enums, and Boolean types. It is useful when you model your domain with those algebraic data types. For example, you might have different contract preferences for users of your app modeled as a sealed class hierarchy:

sealed class Contact {
   data class PhoneCall(val number: String) : Contact()
   data class TextMessage(val number: String) : Contact()
   data class InstantMessage(val type: IMType, val user: String) : Contact()
}

Now, if you write an expression that returns a different result based on different contact preference, the compiler will flag an error if you forget to handle all of the types you have in your app:

fun Rates.computeMessageCost(contact: Contact): Cost =
   when (contact) { // ERROR: 'when' expression must be exhaustive
       is Contact.PhoneCall -> phoneCallCost
       is Contact.TextMessage -> textMessageCost
   }

This is a great help, both in writing code and for future maintenance. If you add a different type of contact preference later, you know that the compiler will make sure you have not forgotten to handle the different types of contact preferences all around your code.

However, before Kotlin 1.6, the following code that uses when statements successfully compiles, even though it totally forgets to handle sending an announcement to your users via instant message:

fun sendAnnouncement(contact: Contact, announcement: Announcement) {
   when (contact) {
       is Contact.PhoneCall -> schedulePhoneCall(contact.number, announcement)
       is Contact.TextMessage -> sendTextMessage(contact.number, announcement)
   }
}

Only a weak IDE inspection was reported, without any messages from the compiler. Starting from Kotlin 1.6, it produces the following compiler warning:

Non-exhaustive 'when' statements on sealed class/interface will be prohibited in 1.7. Add an 'is InstantMessage' branch or 'else' branch instead.

In Kotlin 1.7 it will become an error, leaving no chance to accidentally forget it. Please see KT-47709 for a more detailed explanation of the change and its effects. 

Suspending functions as supertypes

Kotlin 1.6 stabilizes support for implementing suspend functional types as super interfaces. It was one of the missing pieces in the Kotlin coroutines design. 

When you design Kotlin APIs, it is idiomatic to accept functional types when you need to customize the behavior of various library functions. For example, kotlinx.coroutines API has a member function in its Job interface that looks similar to this:

fun invokeOnCompletion(handler: () -> Unit)

You can conveniently use this function with lambdas like invokeOnCompletion { doSomething() }. If you have a class that you wanted to handle the completion with, you can streamline and optimize your code by implementing the functional type () -> Unit directly in your class without creating an additional lambda:

class MyCompletionHandler : () -> Unit {
   override fun invoke() { doSomething() }
}

Starting from Kotlin 1.6 this optimization is possible with suspending functions. If your APIs accept suspending functional types, like this:

public fun launchOnClick(action: suspend () -> Unit) {}

… then you are not limited to passing lambdas and suspending function references to this code anymore. You can implement the corresponding suspending functional types in a class, too:

class MyClickAction : suspend () -> Unit {
   override suspend fun invoke() { doSomething() }
}

Suspend conversions

Kotlin 1.6 stabilizes conversions from regular to suspending functional types. You can now pass any expression of a suitable regular functional type where suspending is expected as a parameter. The compiler will perform a conversion automatically.

This fixes a small but annoying inconsistency in the interaction between regular and suspending functions in Kotlin. In you have a higher-order function that accepts a suspending function, like a collect call on a Kotlin Flow, then instead of using a lambda to call it, like this:

flow.collect { processItem(it) }
fun processItem(item: Item) { /* ... */ }

… you might find it convenient to pass a reference to the processItem function to the collect call to the same effect:

flow.collect(::processItem)

You would then extract a reference to your processing function into a variable in order to customize the behavior in your code. However, that didn’t work in Kotlin versions prior to 1.6. This is because you have a regular function that is being passed as a parameter of a suspending type:

val processingFunction = ::processItem
flow.collect(processingFunction) // ERROR: Type mismatch

In Kotlin 1.6, the above code compiles and works, too.

Improved type inference for recursive generic types

From 1.6.0, the Kotlin compiler can infer a type argument based only on the upper bounds of the corresponding type parameter if it is a recursive generic by default. This makes it possible to create various patterns with recursive generic types that are often used in Java to make builder APIs.

// Before 1.5.30
val containerA = PostgreSQLContainer<nothing>(DockerImageName.parse("postgres:13-alpine")).apply {
    withDatabaseName("db")
    withUsername("user")
    withPassword("password")
    withInitScript("sql/schema.sql")
}

// With compiler option in 1.5.30 or by default starting with 1.6.0
val containerB = PostgreSQLContainer(DockerImageName.parse("postgres:13-alpine"))
    .withDatabaseName("db")
    .withUsername("user")
    .withPassword("password")
    .withInitScript("sql/schema.sql")

Builder inference improvements

Kotlin 1.5.30 introduced the -Xunrestricted-builder-inference compiler option, which made type information about a builder call available to get inside builder lambdas. Namely, it introduced the ability of making calls that return an instance of a not yet inferred type, such as get() inside a buildList() lambda.

Starting with 1.6.0, you don’t need to specify -Xunrestricted-builder-inference to make previously prohibited calls. With the -Xenable-builder-inference compiler option, you can now also write your own generic builders without applying the @BuilderInference annotation and automatically enable builder inference if regular type inference cannot resolve type information.

Supporting previous API versions for a longer period

Starting with Kotlin 1.6.0, you can now develop using three previous API versions instead of two (along with the current stable one). Currently, this includes API versions 1.3, 1.4, 1.5, and 1.6.

Kotlin/JVM

Repeatable annotations with runtime retention. Kotlin, like Java 8, has repeatable annotations. With Kotlin 1.6, the feature is compatible with Java, and @kotlin.annotation.Repeatable now accepts any retention and makes the annotation repeatable both in Kotlin and Java. Java repeatable annotations are now also supported from the Kotlin side.

Kotlin/Native

Now you can try the Experimental version of the new Kotlin/Native memory manager. With this feature we are moving closer to providing a consistent developer experience in multiplatform projects. This means that the new memory manager lifts the existing restrictions on object sharing between threads and provides fully leak-free concurrent programming primitives that are safe and don’t require any special management or annotations from the developers.

You can freely update your Xcode and continue working on your Kotlin projects, as Kotlin/Native now supports Xcode 13

Compilation of Windows targets on any host. You can compile Windows targets mingwX64 and mingwX86 on any host that supports Kotlin/Native.

We’ve reworked the LLVM dependency that Kotlin/Native uses under the hood. This brings some benefits along with an updated LLVM version to 11.1.0 and decreased dependency size.

Unified compiler plugin ABI with JVM and JS IR backends. Now, the Kotlin Multiplatform Gradle plugin is able to use the embeddable compiler jar – the one used for JVM and JS IR backends – for Kotlin/Native. You can now use the same compiler plugin artifacts for Native and other supported platforms.

Kotlin/JS

For building on a server without internet connectivity, you can now disable downloading Node.js and Yarn for Kotlin/JS projects and use the instances already installed on the host.

Kover

Since the first release, precise measurement of code coverage has been a challenge. Some great tools like JaCoCo work with Kotlin code, but they are not fully integrated with our Gradle toolchain and multiplatform projects. In this Kotlin release, we have started to fix this issue. Meet Kover, our new Gradle plugin that measures code coverage for Kotlin code built with the Kotlin/JVM compiler. Now it is in the early development stage and is experimental – we would appreciate your feedback on it in GitHub.

Watch the Kover video for more details.

Standard library

Kotlin 1.6.0 completes three stdlib roadmap items by getting rid of !! after readLine(), stabilizing typeOf(), and providing a Stable Duration API. It also promotes the following stdlib functions to Stable:

  • Collection builders
  • Bit rotation operations on integers
  • Regex function for splitting a string into a sequence

We’ve also added the ability to call compareTo in infix notation and invested in providing a consistent experience with replace() functions on JVM and JS.

New functions for standard input

In Kotlin 1.6.0, we got rid of the need to use the not-null assertion operator !! after reading a line from the standard input in order to improve the experience for newcomers and simplify teaching Kotlin.

We provide new functions for reading from the console with the following experience:

  • readln() throws an exception when EOF has been reached. Use this function instead of checking the result of readLine() for null with the !! operator.
  • The new readlnOrNull() is a null-returning alternative. It behaves in the same way as the former readLine() but has a more representative name.

These functions are now available for JVM and Native. The naming convention for these functions is now consistent with the println() counterpart, which is especially important for newcomers.

fun main() {
    println("Input two integer numbers each on a separate line")
    val num1 = readln().toInt()
    val num2 = readln().toInt()
    println("The sum of $num1 and $num2 is ${num1 + num2}")
}

Stable Duration API

Thanks to your feedback, we have stabilized the Duration API and closed the corresponding roadmap item.

In addition to a more readable output of Duration.toString() and new functions for parsing Duration from String that were available for preview in 1.5.30, the Duration API has received the following changes:

  • The days component of the toComponents function now has the Long type instead of Int to avoid cutting off values.
  • The DurationUnit enum is now not a type alias. There are no cases of using it as a type alias for java.util.concurrent.TimeUnit on JVM.
  • In response to community feedback, we’re bringing back extension properties like Int.seconds. To limit their applicability, they are available only in the Companion of the Duration class.
import kotlin.time.Duration.Companion.seconds

fun main() {
//sampleStart
    val duration = 5000.seconds
    println("There are ${duration.inWholeMinutes} minutes in ${duration.inWholeHours} hours")
//sampleEnd
}

Stable typeOf()

Kotlin 1.6.0 brings Stable typeOf() and closes the corresponding roadmap item. Since 1.3.40, typeOf() has been available on the JVM platform as an experimental API, and now you can use it on any Kotlin platform and get a KType representation of any Kotlin type that the compiler can infer. 

inline fun <reified T> renderType(): String {
    val type = typeOf<T>()
    return type.toString()
}

fun main() {
    val fromExplicitType = typeOf<Int>()
    val fromReifiedType = renderType<List<Int>>()
}

Stable collection builders

Kotlin 1.6.0 promotes collection builder functions – buildMap(), buildList(), and buildSet()– to Stable. Collections returned by the builders are now serializable in their read-only state.

Stable bit rotation operations for integers

In Kotlin 1.6.0, the rotateLeft() and rotateRight() functions, which rotate the binary representation of the number left or right by the specified number of bits, became Stable.

fun main() {
//sampleStart
    val number: Short = 0b10001
    println(number.rotateRight(2).toString(radix = 2)) // 100000000000100
    println(number.rotateLeft(2).toString(radix = 2))  // 1000100
//sampleEnd
}

Stable Regex function for splitting a string into a sequence

Kotlin 1.6.0 also stabilizes splitToSequence() – a function for regular expressions that splits a string into a sequence.

fun main(){
//sampleStart
    val colorsText = "green, red , brown&blue, orange, pink&green"
    val regex = "[,\s]+".toRegex()
    val mixedColor = regex.splitToSequence(colorsText)
        .onEach { println(it) }
        .firstOrNull { it.contains('&') }
    println(mixedColor) // "brown&blue"
//sampleEnd
}

compareTo in infix notation

We’ve added the ability to call the Comparable.compareTo function in infix notation to compare two objects for order: 

class WrappedText(val text: String) : Comparable<WrappedText> {
    override fun compareTo(other: WrappedText): Int =
        this.text compareTo other.text
}

Consistent replace() and replaceFirst() on JVM and JS

Before Kotlin 1.6.0, the replace() and replaceFirst() Regex functions behaved differently on JVM and JS when the replacement string contained a group reference. The behavior on Kotlin/JS is now consistent with that on JVM.

​​Compatibility

As with all feature releases, some deprecation cycles of previously announced changes are coming to an end with Kotlin 1.6.0. All of these cases were carefully reviewed by the language committee and are listed in the Compatibility Guide for Kotlin 1.6. You can also explore these changes on YouTrack.

How to install Kotlin 1.6.0

If you’re using IntelliJ IDEA or Android Studio, your IDE will suggest updating Kotlin to 1.6.0 automatically. Alternatively, you can update manually by following these instructions.

You can download the latest versions of these IDEs to get extensive support for Kotlin:

  • IntelliJ IDEA – for developing Kotlin applications for various platforms.
  • Android Studio –  for developing Android and cross-platform mobile applications.

Make sure that you have also updated the kotlinx libraries to the compatible versions and specified Kotlin 1.6.0 in the build scripts of your existing projects.

If you need the command-line compiler, download it from the Github release page.

If you run into any problems:

Stay up to date with the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form to the right of this post.

What else to read and watch

Top issue reporters from YouTrack 

Ryan Nett (48 issues), Zac Sweers (22 issues), Tianyu Geng (18 issues), zhelenskiy (18 issues), Thodoris Sotiropoulos (15 issues), AndroidDeveloperLB (14 issues), Morgan, Bartholomew (14 issues), Mikhail Naftal (14 issues), Louis CAD (12 issues), Philip Wedemann (12 issues), Victor Turansky (11 issues), Igor Wojda (11 issues), Martin Bonnin (11 issues), Iaroslav Postovalov (11 issues), Cedric (10 issues), (9 issues), Ben Woodworth (8 issues), Tianyi Guan (8 issues), Chris Povirk (8 issues), Alon Albert (8 issues).

External contributors

We’d like to thank all of our contributors whose pull requests were included in this release: Pyos, Tianyu Geng, Jinseong Jeon, Steven Schäfer, Mark Punzalan, Hung Nguyen, Mads Ager, Ting-Yuan Huang, Matthew Gharrity, Ivan Gavrilovic, Xin Wang, ov7a, Jiaxiang Chen, Yigit Boyar, Bingran, bracadabra, Steffi Stumpos.

Continue ReadingKotlin 1.6.0 Released

Kotlin 1.5.30 Is Now Available!

Since Kotlin 1.5.30 is the last incremental release before Kotlin 1.6.0, it includes many experimental language and standard library features that we are planning to release in Kotlin 1.6.0. Give them a try and share your feedback with us, you can really influence the final result! These experimental features include sealed when statements, changes to opt-in requirements, instantiation of annotation classes, improvements to the Duration and Regex stdlib APIs, and more.

With Kotlin 1.5.30, you can also enjoy native support for Apple silicon, the promotion of the Kotlin/JS IR backend to Beta, the ability to use custom cinterop libraries in the shared native code of multiplatform applications, support for Java toolchains provided by the Kotlin Gradle plugin, and much more.

Update to Kotlin 1.5.30

This blog post provides an overview of the updates in this release:

  • Language improvements, including sealed when statements, support for suspend functions as supertypes, and changes to opt-in requirements.
  • Multiplatform improvements, including the ability to use custom cinterop libraries in shared native code and support for XCFrameworks as an output format.
  • Kotlin/JVM improvements, including instantiation of annotation classes and improved configuration of nullability annotation support.
  • Kotlin/Native improvements, including native support for Apple silicon and an improved Kotlin DSL for the CocoaPods Gradle plugin.
  • Kotlin/JS IR improvements, including the promotion of the JS IR backend to Beta and a better debugging experience for the new backend.
  • Gradle improvements, including support for Java toolchains and easier ways to explicitly set the Kotlin daemon’s JVM arguments.
  • Standard library improvements for the Duration and Regex APIs.

Automatically update to Kotlin 1.5.30

If you use IntelliJ IDEA or Android Studio, you have the option to automatically update to the new Kotlin release as soon as it becomes available.

Learn more about installing Kotlin 1.5.30.

Stay up to date with information about the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form to the right of this post.

Language

The Kotlin roadmap includes adding support for sealed when statements, releasing opt-in annotations, improving type inference, and stabilizing builder inference. 

Kotlin 1.5.30 takes a step down this road by providing a preview of these features, whose release is planned for 1.6.0.

Sealed when statements

Sealed when is a long awaited feature with more than 280 votes in YouTrack. If you enable this feature in 1.5.30, the Kotlin compiler will warn if one of your when statements is not exhaustive. This will make your code safer without you having to introduce your own functions.

Give this feature a try and provide your feedback in this YouTrack ticket

Support for suspend functions as supertypes

Kotlin 1.5.30 provides a preview of an ability to use suspend functional types as super interfaces, although it has some limitations. It’s one of the missing pieces in the Kotlin coroutines design.

class MyClass: suspend () -> Unit {
    override suspend fun invoke() { TODO() }
}

Enable this feature, give it a try, and provide your feedback in this YouTrack ticket.

Changes to opt-in requirements

As a further step toward the release of opt-in annotations, Kotlin 1.5.30:

  • Presents new rules for using and declaring opt-in requirement annotations on different targets. 
  • Requires opt-in even for implicit usages of an experimental API. For example, if the function’s return type is marked as an experimental API element, a usage of the function requires you to opt-in even if the declaration is not marked as requiring an opt-in explicitly.
// Library code

@RequiresOptIn(message = "This API is experimental.")
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS)
annotation class MyDateTime // Opt-in requirement annotation

@MyDateTime
class DateProvider // A class requiring opt-in

// Client code

// Warning: experimental API usage
fun createDateSource(): DateProvider { /* ... */ }

fun getDate(): Date {
    val dateSource = createDateSource() // Also warning: experimental API usage
    // ... 
}

Try out the changes and share your feedback in this YouTrack ticket

Learn more about opt-in requirements

Improvements to type inference on recursive generic types 

With type inference on recursive generic types enabled, the Kotlin 1.5.30 compiler can infer a type argument based only on the upper bounds of the corresponding type parameter if it is a recursive generic. This makes it possible to create various patterns with recursive generic types that are often used in Java to make builder APIs.

// Kotlin 1.5.20
val containerA = PostgreSQLContainer<Nothing>(DockerImageName.parse("postgres:13-alpine")).apply {
    withDatabaseName("db")
    withUsername("user")
    withPassword("password")
    withInitScript("sql/schema.sql")
}

// Kotlin 1.5.30
val containerB = PostgreSQLContainer(DockerImageName.parse("postgres:13-alpine"))
    .withDatabaseName("db")
    .withUsername("user")
    .withPassword("password")
    .withInitScript("sql/schema.sql")

Eliminating builder inference restrictions 

With eliminating builder inference restrictions enabled, Kotlin 1.5.30 removes a builder inference restriction. Not only can you specify the type information that builder inference can infer, but you can also use the get function on it. For example, you can call get() inside a lambda argument of buildList() without explicitly specified type arguments.

Kotlin Multiplatform

Kotlin 1.5.30 includes the following improvements for Kotlin Multiplatform:

  • Ability to use custom cinterop libraries in shared native code, which extends the ability to share platform-dependent libraries shipped with Kotlin/Native. 
  • Support for XCFrameworks as an output format for all Kotlin Multiplatform projects. XCFrameworks help gather logic for all the target platforms and architectures in a single bundle and don’t require removing unnecessary architectures before publishing the application to AppStore.
  • New default publishing setup for Android artifacts. This setup will be compatible with any build type (like debug or release)  by default. Before 1.5.30, the metadata generated by the maven-publish Gradle plugin when publishing a multiplatform library for Android included the build type attribute for every published Android variant. This made it compatible only with the same build type used by the library consumer. 

Kotlin/JVM

With Kotlin 1.5.30, Kotlin/JVM gets the following updates:

annotation class InfoMarker(val info: String)

fun processInfo(marker: InfoMarker) = ...

fun main(args: Array<String>) {
    if (args.size != 0)
        processInfo(getAnnotationReflective(args))
    else
        processInfo(InfoMarker("default"))
}

Kotlin/Native

Kotlin 1.5.30 provides the following improvements for Kotlin/Native:

Kotlin/JS

Kotlin 1.5.30 provides the following improvements for Kotlin/JS:

Gradle

Kotlin 1.5.30 introduces the following features to improve the Kotlin Gradle plugin user experience:

  • Support for Java toolchains. Gradle 6.7 introduced support for Java toolchains, which make it easy to select a JDK for project compilation. Just declare the version you need in the build script and Gradle does the rest, finding it on your host machine or even downloading and installing it if it’s not there yet. The Kotlin Gradle plugin supports Java toolchains for Kotlin/JVM compilation tasks. For Gradle versions 6.1-6.6, set a JDK home with the UsesKotlinJavaToolchain interface.
  • Easier ways to explicitly specify Kotlin daemon JVM arguments. If nothing is specified for the Kotlin daemon, it inherits arguments from the Gradle daemon. You can now also specify arguments for a specific task, as well as for the Kotlin extension, as a single line in build.gradle.kts or gradle.properties.

build.gradle.kts

kotlin {
    kotlinDaemonJvmArgs = listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC")
}

gradle.properties

kotlin.daemon.jvmargs = -Xmx486m -Xms256m -XX:+UseParallelGC

Standard library

Kotlin 1.5.30 brings improvements to the standard library’s Duration and Regex APIs:

Duration API improvements

As indicated in our libraries roadmap, we’re going to stabilize the Duration API in Kotlin 1.6.0, which means this is the last chance to give it a try and share your feedback with us on anything you’d like changed. We would appreciate your feedback in this KEEP.

Kotlin 1.5.30 provides a preview of API improvements. The output of Duration.toString() is now more readable. For example, Duration.minutes(920).toString() produces 15h 20m instead of the previous 920m.

A negative duration is now prefixed with a minus sign (-), and it is surrounded by parentheses if it consists of multiple components: -12m and -(1h 30m).

This release also provides a preview of new functions for parsing Duration from String:

  • parse() parses Duration objects from strings formatted as Duration’s toString() or from strings representing ISO 8601 durations (such as toIsoString() outputs).
  • parseIsoString() parses Duration objects from strings representing ISO 8601 durations.
  • *OrNull() counterparts for both functions.
import kotlin.time.Duration
import kotlin.time.ExperimentalTime

@ExperimentalTime
fun main() {
//sampleStart
    val isoFormatString = "PT1H30M"
    val defaultFormatString = "1h 30m"
    println(Duration.parse(isoFormatString)) // "1h 30m"
    println(Duration.parse(defaultFormatString)) // "1h 30m"
//sampleEnd
}

Regex API improvements

Kotlin 1.5.30 provides new experimental functions for regular expressions:

  • matchesAt() checks whether a regex has a match in the specified position of a String.
  • matchAt() returns the match if one is found.
fun main(){
//sampleStart
    val releaseText = "Kotlin 1.5.30 is released!"
    val versionRegex = "\d[.]\d[.]\d+".toRegex()
    println(versionRegex.matchAt(releaseText, 0)) // "null"
    println(versionRegex.matchAt(releaseText, 7)?.value) // "1.5.30"
//sampleEnd
}
  • splitToSequence() is a lazy counterpart of split(). It splits the string around matches of the given regex, but returns the result as a Sequence. A similar function has also been added to CharSequence.
fun main(){
//sampleStart
    val colorsText = "green, red , brown&blue, orange, pink&green"
    val regex = "[,\s]+".toRegex()
    val mixedColor = regex.splitToSequence(colorsText)
        .onEach { println(it) }
        .firstOrNull { it.contains('&') }
    println(mixedColor) // "brown&blue"
//sampleEnd
}

How to install Kotlin 1.5.30

If you already use IntelliJ IDEA or Android Studio, your IDE will suggest updating Kotlin to 1.5.30 automatically. You can also update manually by following these instructions

You can download the latest versions of these IDEs to get extensive support for Kotlin:

  • IntelliJ IDEA – for developing Kotlin applications for various platforms.
  • Android Studio –  for developing Android and cross-platform mobile applications.

Make sure that you have also updated the kotlinx libraries to compatible versions and specified version 1.5.30 of Kotlin in the build scripts of your existing projects.

If you need the command-line compiler, download it from the Github release page.

If you run into any problems

Stay up to date with information about the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form to the right of this post.

Read and watch more

External contributors 👏👏👏

We’d like to thank all of our external contributors whose pull requests were included in this release:

Jinseong Jeon, pyos, Tianyu Geng, Mark Punzalan, Mads Ager, Ivan Gavrilovic, Steven Schäfer, Vladimir Ivanov, Hung Nguyen, Matthew Gharrity, Jiaxiang Chen, Ivan Kochurkin, Iaroslav Postovalov, Toshiaki Kameyama, Udi Cohen, Xin Wang, bracadabra

Continue ReadingKotlin 1.5.30 Is Now Available!

Kotlin 1.5.30 Is Now Available!

Since Kotlin 1.5.30 is the last incremental release before Kotlin 1.6.0, it includes many experimental language and standard library features that we are planning to release in Kotlin 1.6.0. Give them a try and share your feedback with us, you can really influence the final result! These experimental features include sealed when statements, changes to opt-in requirements, instantiation of annotation classes, improvements to the Duration and Regex stdlib APIs, and more.

With Kotlin 1.5.30, you can also enjoy native support for Apple silicon, the promotion of the Kotlin/JS IR backend to Beta, the ability to use custom cinterop libraries in the shared native code of multiplatform applications, support for Java toolchains provided by the Kotlin Gradle plugin, and much more.

Update to Kotlin 1.5.30

This blog post provides an overview of the updates in this release:

  • Language improvements, including sealed when statements, support for suspend functions as supertypes, and changes to opt-in requirements.
  • Multiplatform improvements, including the ability to use custom cinterop libraries in shared native code and support for XCFrameworks as an output format.
  • Kotlin/JVM improvements, including instantiation of annotation classes and improved configuration of nullability annotation support.
  • Kotlin/Native improvements, including native support for Apple silicon and an improved Kotlin DSL for the CocoaPods Gradle plugin.
  • Kotlin/JS IR improvements, including the promotion of the JS IR backend to Beta and a better debugging experience for the new backend.
  • Gradle improvements, including support for Java toolchains and easier ways to explicitly set the Kotlin daemon’s JVM arguments.
  • Standard library improvements for the Duration and Regex APIs.

Automatically update to Kotlin 1.5.30

If you use IntelliJ IDEA or Android Studio, you have the option to automatically update to the new Kotlin release as soon as it becomes available.

Learn more about installing Kotlin 1.5.30.

Stay up to date with information about the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form to the right of this post.

Language

The Kotlin roadmap includes adding support for sealed when statements, releasing opt-in annotations, improving type inference, and stabilizing builder inference. 

Kotlin 1.5.30 takes a step down this road by providing a preview of these features, whose release is planned for 1.6.0.

Sealed when statements

Sealed when is a long awaited feature with more than 280 votes in YouTrack. If you enable this feature in 1.5.30, the Kotlin compiler will warn if one of your when statements is not exhaustive. This will make your code safer without you having to introduce your own functions.

Give this feature a try and provide your feedback in this YouTrack ticket

Support for suspend functions as supertypes

Kotlin 1.5.30 provides a preview of an ability to use suspend functional types as super interfaces, although it has some limitations. It’s one of the missing pieces in the Kotlin coroutines design.

class MyClass: suspend () -> Unit {
    override suspend fun invoke() { TODO() }
}

Enable this feature, give it a try, and provide your feedback in this YouTrack ticket.

Changes to opt-in requirements

As a further step toward the release of opt-in annotations, Kotlin 1.5.30:

  • Presents new rules for using and declaring opt-in requirement annotations on different targets. 
  • Requires opt-in even for implicit usages of an experimental API. For example, if the function’s return type is marked as an experimental API element, a usage of the function requires you to opt-in even if the declaration is not marked as requiring an opt-in explicitly.
// Library code

@RequiresOptIn(message = "This API is experimental.")
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS)
annotation class MyDateTime // Opt-in requirement annotation

@MyDateTime
class DateProvider // A class requiring opt-in

// Client code

// Warning: experimental API usage
fun createDateSource(): DateProvider { /* ... */ }

fun getDate(): Date {
    val dateSource = createDateSource() // Also warning: experimental API usage
    // ... 
}

Try out the changes and share your feedback in this YouTrack ticket

Learn more about opt-in requirements

Improvements to type inference on recursive generic types 

With type inference on recursive generic types enabled, the Kotlin 1.5.30 compiler can infer a type argument based only on the upper bounds of the corresponding type parameter if it is a recursive generic. This makes it possible to create various patterns with recursive generic types that are often used in Java to make builder APIs.

// Kotlin 1.5.20
val containerA = PostgreSQLContainer<Nothing>(DockerImageName.parse("postgres:13-alpine")).apply {
    withDatabaseName("db")
    withUsername("user")
    withPassword("password")
    withInitScript("sql/schema.sql")
}

// Kotlin 1.5.30
val containerB = PostgreSQLContainer(DockerImageName.parse("postgres:13-alpine"))
    .withDatabaseName("db")
    .withUsername("user")
    .withPassword("password")
    .withInitScript("sql/schema.sql")

Eliminating builder inference restrictions 

With eliminating builder inference restrictions enabled, Kotlin 1.5.30 removes a builder inference restriction. Not only can you specify the type information that builder inference can infer, but you can also use the get function on it. For example, you can call get() inside a lambda argument of buildList() without explicitly specified type arguments.

Kotlin Multiplatform

Kotlin 1.5.30 includes the following improvements for Kotlin Multiplatform:

  • Ability to use custom cinterop libraries in shared native code, which extends the ability to share platform-dependent libraries shipped with Kotlin/Native. 
  • Support for XCFrameworks as an output format for all Kotlin Multiplatform projects. XCFrameworks help gather logic for all the target platforms and architectures in a single bundle and don’t require removing unnecessary architectures before publishing the application to AppStore.
  • New default publishing setup for Android artifacts. This setup will be compatible with any build type (like debug or release)  by default. Before 1.5.30, the metadata generated by the maven-publish Gradle plugin when publishing a multiplatform library for Android included the build type attribute for every published Android variant. This made it compatible only with the same build type used by the library consumer. 

Kotlin/JVM

With Kotlin 1.5.30, Kotlin/JVM gets the following updates:

annotation class InfoMarker(val info: String)

fun processInfo(marker: InfoMarker) = ...

fun main(args: Array<String>) {
    if (args.size != 0)
        processInfo(getAnnotationReflective(args))
    else
        processInfo(InfoMarker("default"))
}

Kotlin/Native

Kotlin 1.5.30 provides the following improvements for Kotlin/Native:

Kotlin/JS

Kotlin 1.5.30 provides the following improvements for Kotlin/JS:

Gradle

Kotlin 1.5.30 introduces the following features to improve the Kotlin Gradle plugin user experience:

  • Support for Java toolchains. Gradle 6.7 introduced support for Java toolchains, which make it easy to select a JDK for project compilation. Just declare the version you need in the build script and Gradle does the rest, finding it on your host machine or even downloading and installing it if it’s not there yet. The Kotlin Gradle plugin supports Java toolchains for Kotlin/JVM compilation tasks. For Gradle versions 6.1-6.6, set a JDK home with the UsesKotlinJavaToolchain interface.
  • Easier ways to explicitly specify Kotlin daemon JVM arguments. If nothing is specified for the Kotlin daemon, it inherits arguments from the Gradle daemon. You can now also specify arguments for a specific task, as well as for the Kotlin extension, as a single line in build.gradle.kts or gradle.properties.

build.gradle.kts

kotlin {
    kotlinDaemonJvmArgs = listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC")
}

gradle.properties

kotlin.daemon.jvmargs = -Xmx486m -Xms256m -XX:+UseParallelGC

Standard library

Kotlin 1.5.30 brings improvements to the standard library’s Duration and Regex APIs:

Duration API improvements

As indicated in our libraries roadmap, we’re going to stabilize the Duration API in Kotlin 1.6.0, which means this is the last chance to give it a try and share your feedback with us on anything you’d like changed. We would appreciate your feedback in this KEEP.

Kotlin 1.5.30 provides a preview of API improvements. The output of Duration.toString() is now more readable. For example, Duration.minutes(920).toString() produces 15h 20m instead of the previous 920m.

A negative duration is now prefixed with a minus sign (-), and it is surrounded by parentheses if it consists of multiple components: -12m and -(1h 30m).

This release also provides a preview of new functions for parsing Duration from String:

  • parse() parses Duration objects from strings formatted as Duration’s toString() or from strings representing ISO 8601 durations (such as toIsoString() outputs).
  • parseIsoString() parses Duration objects from strings representing ISO 8601 durations.
  • *OrNull() counterparts for both functions.
import kotlin.time.Duration
import kotlin.time.ExperimentalTime

@ExperimentalTime
fun main() {
//sampleStart
    val isoFormatString = "PT1H30M"
    val defaultFormatString = "1h 30m"
    println(Duration.parse(isoFormatString)) // "1h 30m"
    println(Duration.parse(defaultFormatString)) // "1h 30m"
//sampleEnd
}

Regex API improvements

Kotlin 1.5.30 provides new experimental functions for regular expressions:

  • matchesAt() checks whether a regex has a match in the specified position of a String.
  • matchAt() returns the match if one is found.
fun main(){
//sampleStart
    val releaseText = "Kotlin 1.5.30 is released!"
    val versionRegex = "\d[.]\d[.]\d+".toRegex()
    println(versionRegex.matchAt(releaseText, 0)) // "null"
    println(versionRegex.matchAt(releaseText, 7)?.value) // "1.5.30"
//sampleEnd
}
  • splitToSequence() is a lazy counterpart of split(). It splits the string around matches of the given regex, but returns the result as a Sequence. A similar function has also been added to CharSequence.
fun main(){
//sampleStart
    val colorsText = "green, red , brown&blue, orange, pink&green"
    val regex = "[,\s]+".toRegex()
    val mixedColor = regex.splitToSequence(colorsText)
        .onEach { println(it) }
        .firstOrNull { it.contains('&') }
    println(mixedColor) // "brown&blue"
//sampleEnd
}

How to install Kotlin 1.5.30

If you already use IntelliJ IDEA or Android Studio, your IDE will suggest updating Kotlin to 1.5.30 automatically. You can also update manually by following these instructions

You can download the latest versions of these IDEs to get extensive support for Kotlin:

  • IntelliJ IDEA – for developing Kotlin applications for various platforms.
  • Android Studio –  for developing Android and cross-platform mobile applications.

Make sure that you have also updated the kotlinx libraries to compatible versions and specified version 1.5.30 of Kotlin in the build scripts of your existing projects.

If you need the command-line compiler, download it from the Github release page.

If you run into any problems

Stay up to date with information about the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form to the right of this post.

Read and watch more

External contributors 👏👏👏

We’d like to thank all of our external contributors whose pull requests were included in this release:

Jinseong Jeon, pyos, Tianyu Geng, Mark Punzalan, Mads Ager, Ivan Gavrilovic, Steven Schäfer, Vladimir Ivanov, Hung Nguyen, Matthew Gharrity, Jiaxiang Chen, Ivan Kochurkin, Iaroslav Postovalov, Toshiaki Kameyama, Udi Cohen, Xin Wang, bracadabra

Continue ReadingKotlin 1.5.30 Is Now Available!

Improved IDE Performance, Better Debugging Experience, and More for Kotlin in Latest IntelliJ IDEA

Enjoy improved performance, a better coroutines debugging experience, WSL 2 and Run Targets support, and more improvements for Kotlin in IntelliJ IDEA 2021.2:

Auto-update to this new release

IntelliJ IDEA will give you the option to automatically update to the new release as soon as it is available.

If you are not yet an IntelliJ IDEA user, you can download the newest version.

Performance improvements

IntelliJ IDEA 2021.2 brings some major performance improvements for Kotlin.

Faster test files analysis

Now you can run tests before code analysis finishes. The Run test icon appears in the gutter as soon as you open the file and you can run your test immediately.

Run and debug your code before the IDE finishes indexing

The indexing process in the IDE and running code are now autonomous from each other. You can run or debug the project right away without waiting for the IDE to finish its work.

Improved speed of rename refactoring

Rename refactoring for particular cases, like for fields with common names name or id, became faster. Check out this YouTrack issue for more details.

Shared indexes for new Spring Boot projects

Shared indexes help you to prevent situations where you open a project and need to wait for indexing to finish. In the previous version of IntelliJ IDEA you can download the JDK shared indexes that save time during every project import. Now shared indexes are available for Spring Boot projects. Learn more about how to download and use shared indexes in the IntelliJ IDEA documentation.

Better debugging experience

IntelliJ IDEA 2021.2 brings useful improvements and updates to the coroutine agent in the debugger.

Evaluate suspend functions

Now you can evaluate suspend function calls during the debugging process. You can put a breakpoint and evaluate the suspend function:

Suspend function evaluation

Look through these YouTrack tickets for more details: KT-27974, KT-31701.

Preserving variables after suspension points

Previously, when local variables were not used after passing a suspension point, you couldn’t see their values in the Local Variable table. This helped avoid memory leaks, but as a side effect such variables disappeared in the Variables view of the Debugger tool window. Now you can see the values of such variables for common cases. IntelliJ IDEA also handles other specific cases properly and notifies you when it is impossible to obtain the value.

For example, when you debug through the following code, the debugger shows the message that the x1, x2, x3 variables have been optimized out:

Preserving variables after suspension

Check out these YouTrack issues for more details: KTIJ-18499, KTIJ-18630.

Coroutines extension support in Java, Maven, and Spring run configurations

The coroutines agent is now available for Java, Maven, and Spring run configurations with a dependency on kotlinx.coroutines.

Remote development support

Some popular remote-development scenarios are now available for Kotlin projects: WSL 2 support and Run Targets feature.

Run, debug, and test your code in different remote environments without leaving the IDE.

Kotlin plugin in the IntelliJ IDEA repository

The Kotlin plugin code has been moved to the IntelliJ IDEA repository. That means that every stable IDE release improves your Kotlin experience and brings you more debugging, refactoring, and IDE-related features.

To contribute to the Kotlin plugin, clone the IntelliJ IDEA repository.

Since the Kotlin plugin and Kotlin have separate release cycles, this creates some limitations that are important to emphasize:

  • The EAP version of Kotlin works only with the stable version of the IDE. That means that you can’t install the Kotlin EAP version to the EAP IDEA release.
  • The Kotlin plugin is based on the previous stable version of the Kotlin compiler. You can still update the Kotlin version in your project, but some IDE-related features might not be available. We are working on stabilizing the process so that the next versions of the plugin will be based on the latest stable version of the compiler.

Learn more about the EAP for Kotlin and IntelliJ IDEA.

Other IDE improvements

IntelliJ IDEA 2021.2 also brings more IDE features that improve the Kotlin experience.

Automatic ML code completion

Kotlin code completion works based on a machine learning mechanism by default. Code suggestions are prioritized more carefully as IntelliJ IDEA considers the choices of thousands of real users in similar situations. You can configure ML-assisted completion in Preferences/Settings | Editor | Code Completion.

Clickable inlay hints

Now you can click the type in the inlay hint and look through the declaration of the type, including generics types. Just hold Cmd + click the type in the hint:

 You can customize the inlay hints’ appearance in Preferences | Editor | Inlay hints | Kotlin.

Package Search integration

Package Search now works with build.gradle.kts files. This feature allows you to upgrade, downgrade, and remove existing dependencies. You can use it to find new dependencies and add them automatically. Package Search will add the required repositories to your build script if they’re missing.

Advanced settings

There is a new node Advanced Settings in the Preferences | Settings window. It contains some use-case-specific options conveniently grouped by the IDE tool.
For example, you can add a left margin in Distraction-free mode, or set the maximum number of recent projects which are displayed in the File | Open Recent menu.

Quick access to Eclipse projects

IntelliJ IDEA detects existing Eclipse projects automatically and adds them to the Welcome screen. To try this feature, select Open existing Eclipse projects on your first IDE launch.

See also

  • What’s new in IntelliJ IDEA 2021.2 – docs and video
  • What’s new for Kotlin in IntelliJ IDEA 2021.1 – blog post
Continue ReadingImproved IDE Performance, Better Debugging Experience, and More for Kotlin in Latest IntelliJ IDEA

End of content

No more pages to load