K2 compiler migration guideを読む

# K2 compiler migration guideが公開された
- [K2 compiler migration guide](https://kotlinlang.org/docs/k2-compiler-migration-guide.html)
- [What's new in Kotlin 2.0.0-RC3](https://kotlinlang.org/docs/whatsnew-eap.html) // このURLの中身はどんどん更新されるので注意


# K2 compilerになってどうなる
-  K2 compilerになってfrontend compilerがKotlinで書き直された
-  frontend compilerはsemantic analysis（セマンティック解析), call resolution（呼び出し解決), and type inference（型推論)を担当している
-  compilerがコードを解析していざなにかをしようとするまでの時間が早くなるということ
-  以下ざーっと読んだ内容
-  解釈が間違っていれば指摘してください

# Changes
## Immediate initialization of open properties with backing fields

- openなpropertyの即時初期化が必要になる
- openなpropertyは基本的に初期値を与えるのが推奨されるが、どうしても初期化したくない場合は`final`を付与したpropertyする

```kotlin
open class Base {
    open val a: Int
    open var b: Int

    init {
        // Kotlin 1.9ではOK、Kotlin 2ではエラー
        this.a = 1
        // Kotln 1.9でもエラー
        this.b = 1
    }
}

class Derived : Base() {
    override val a: Int = 2
    override var b = 2
}
```

## Deprecated synthetic setters on a projected receiver

- Genericsを取るJavaのsetter関数を異なる型で呼び出すとエラーになるようになる

```java
public class Container<E> {
    public E getFoo() {
        return null;
    }
    public void setFoo(E foo) {}
}
```

```kotlin
fun exampleFunction(starProjected: Container<*>, inProjected: Container<in Number>, sampleString: String) {
    // Kotlin 1.9以前もエラー
    // Nothing型を要求するのでエラーになる
    starProjected.setFoo(sampleString)
    
    // `foo`は`setFoo()`に解決される, Nothing型を要求するが型不一致でもエラーにならず実行時にエラーとなる
    // Kotlin 2からエラーになる
    starProjected.foo = sampleString

    // Kotlin 1.9以前もエラー
    // 数値型を要求するのでエラーになる
    inProjected.setFoo(sampleString)

    // `foo`は`setFoo()`に解決される, 数値型を要求するが型不一致でもエラーにならず実行時にエラーとなる
    // Kotlin 2からエラーになる
    inProjected.foo = sampleString
}
```


## Forbidden function calls with inaccessible types

- 解決できない型パラメータを持つラムダ関数をもつ関数の呼び出し、一部のGenericsがコンパイルエラーになるようになった

```kotlin
// module one
class Some(val x: Int)

// module two
// build.gradleでimplementation(module.one)している

// module twoはSome型にアクセスできるため両方の関数はコンパイルできる
fun foo(f: (Some, String) -> Unit) {}
fun bar(f: (Some) -> Unit) {}

class Generic<T>

fun gen() = Generic<Some<String>>()
fun takeString(g: Generic<Some<String>>) {}

// module three
// build.gradleでimplementation(module.two)している
fun test() {
    // unused propertyがmodule threeではアクセスできないSome型のためKotlin 2ではエラーになる
    foo { _, _ -> }

    // module threeではアクセスできないSome型をとるためwarningになる
    foo { some, str -> }

    // Genericsで隠蔽されているためKotlin 2ではwarningになる
    val z = gen()

    // module threeでアクセスできないSome型の引数をとるためKotlin 2ではエラーになる
    takeString(z)
}

```


## Consistent resolution order of Kotlin properties and Java fields with the same name

- Javaクラスを継承したKotlinクラスで同名のプロパティを持つ際の解決が一貫性を持つようになった
- 基本的にサブクラスのpropertyが優先される
- Kotlinクラスを継承したJavaクラスも同様にサブクラスのプロパティが優先される

```java
public class Base {
    public String a = "a";
    public String b = "b";
}
```

```kotlin
class Derived : Base() {
    val a = "aa"
    val b
      get() = "bb"
}

fun main() {
    val derived = Derived()
    // Derived.aに解決される
    println(derived.a)

    // カスタムゲッターの挙動が変わる
    // Kotlin 1.9以前 Base.bに解決される -> b
    // Kotlin 2 Derived.bに解決される -> bb
    println(derived.b)
}
```


## Improved null safety for Java primitive arrays

- Kotlin 2からTYPE_USEなannotationが付与されているJava配列（Array）のnullabilityが正しく推論されるようになった
- TYPE_USEなannotation以外はKotlin 2でも変更はない

```java
interface DataProvider {
    int @Nullable [] fetchData();
}
```

```kotlin
val dataService: DataProvider = object : DataProvider {}

val data = dataService.fetchData()

// Kotlin 1.9以前
// dataはIntArrayに解決される
// 呼び出し時にNPEが発生する可能性がある
data[0]

// Kotlin 2
// dataはIntArray?に解決される
data?.get(0)
```

# Smart cast improvements
## Local variables and further scopes

- `if`, `when`外で判定した条件がblock内で判定されるようになる
- instanceの型がなんなのかというのを意味にある名前で変数とできる

```kotlin
class Cat {
    fun purr() {
        println("Purr purr")
    }
}

fun petAnimal(animal: Any) {
    val isCat = animal is Cat
    if (isCat) {
        // Kotlin　1.9以前: すでに判定済みでもasやcheckで型を指定しないと呼べない
        (animas as Cat).purr()
        
        // Kotlin　2.0: if外の条件についてもfrontend compilerが考慮してくれる
        animal.purr()
    }
}
```

## Type checks with the logical or operator

- or(||)の条件について正確に読み取ってくれるようになる

```kotlin
interface Status {
    fun signal() {}
}

interface Ok : Status
interface Postponed : Status
interface Declined : Status

fun signalCheck(signalStatus: Any) {
    if (signalStatus is Postponed || signalStatus is Declined) {
        // Kotlin　1.9以前: asやcheckで型を指定しないと呼べない、かつasやcheckを行ったあとの行はStatusとしか認識できない
        (signalStatus as Status).signal()

        // Kotlin 2.0: Status interfaceであることは明示的なため呼べる
        signalStatus.signal()
    }
}
```

## Inline functions

- inline関数内の変数観測が正しくなり余計なnullabilityを気にする必要がなくなった

```kotlin
interface Processor {
    fun process()
}

inline fun inlineAction(f: () -> Unit) = f()

fun nextProcessor(): Processor? = null

fun runProcessor(): Processor? {
    var processor: Processor? = null
    inlineAction {
        if (processor != null) {
            // Kotlin　1.9以前:
            processor?.process()
            
            // Kotlin 2.0: 展開された関数中ではすでにnullチェック済みなのでそのまま呼べる
            processor.process()
        }

        processor = nextProcessor()
    }

    return processor
}
```

## Properties with function types

```kotlin
interface Provider {
    operator fun invoke()
}

interface Processor : () -> String

class Holder(val provider: Provider?, val processor: Processor?) {
    fun process() {
        if (provider != null) {
            // Kotlin　1.9以前: invokeを呼ぶ必要がある
            provider.invoke()

            // Kotlin 2.0: nullチェック済みなので直接operator functionを呼べる
            provider()
        }
        if (processor != null) {
            // Kotlin　1.9以前: invokeを呼ぶ必要がある
            processor.invoke()

            // Kotlin 2.0: nullチェック済みなので直接operator functionを呼べる
            processor()
        }
    }
}
```

## Exception handling

- `catch`と`finally`の型推論が向上した


```kotlin
fun testString() {
    var stringInput: String? = null
    stringInput = ""
    try {
        // 文字列代入後なのでcompilerはnon-null判定
        println(stringInput.length)

        stringInput = null

        // 処理途中でexceptionを投げる
        if (2 > 1) throw Exception()
        stringInput = ""
    } catch (exception: Exception) {
        // Kotlin　1.9以前: try句の前に文字列を代入しているのでStringでcatch句を書く（NullPointExceptionの可能性がある)
        // Kotlin 2.0: stringInputがnullの可能性があるためString?でcatch句を書く
        println(stringInput?.length)
    }
}
```


## Increment and decrement operators

- inc, decメソッドの型推論バグが修正された

```kotlin
interface Rho {
    operator fun inc(): Sigma = TODO()
}

interface Sigma : Rho {
    fun sigma() = Unit
}

interface Tau {
    fun tau() = Unit
}

fun main(input: Rho) {
    var unknownObject: Rho = input
    if (unknownObject is Tau) {

        // incrementでSigma型になる
        ++unknownObject

        // Kotlin　1.9以前: unresolved reference
        // Kotlin 2.0.0: callable
        unknownObject.sigma()

        // Kotlin　1.9以前: callableだが呼び出すとエラーになる
        // Kotlin 2.0.0: 既にTau型でなくなっているのでunresolved reference
        unknownObject.tau()
    }
}
```

# Kotlin Multiplatform improvements
## Separation of common and platform sources during compilation

- KMPは共通で使用するcommonコードと各platformで使用するplatformコードをそれぞれ別に記述することができるため同名・同引数の関数を作成できる
- ![basic-project-structure-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608715/9df9e561-429b-9610-ff27-3e512fb34e6f.png)
- Kotlin 1.9以前ではcompile時にcommonコードとplatformコードをごっちゃにして取り扱っていた
- Kotlin 2.0ではcommonコードとplatformコードがisolateされる
- 同名関数をcommonコードとplatformコードを定義し呼び出した場合の挙動が変更される
- ただし引数の型が異なる関数を定義するなどoverloadを使用する場合は以前の挙動になったりするところもある


表. 同名関数をcommonコードとplatformコードを定義し呼び出した場合の挙動

| --- | Kotlin 1.9以前 | Kotlin 2.0 |
| --- | --- | --- |
| JVM | JVM platformコード | commonコード |
| JVM以外 | commonコード | commonコード |


## Different visibility levels of expected and actual declarations
- [expect/actual](https://kotlinlang.org/docs/multiplatform-expect-actual.html)はplatformごとの実装を分けるための仕組み
- Kotlin 1.9以前ではexpect/actualでそれぞれ定義したものは同一のvisibilityを設定する必要があった
- Kotlin 2.0ではstrictでない方向性（見える範囲が広がる方向）への変更は許容されるようになる

```kotlin
expect internal class Attribute
// internal -> publicなのでOK
actual class Attribute

// actualでtypealiasを使うときはvisibility設定はstrictでないようにならなければならない
expect internal class Attribute
internal actual typealias Attribute = Expanded
class Expanded
```


# Compiler plugins support

- 公式のpluginは大体対応されている
- kaptも対応するらしい
- compose, KSPももちろん対応進んでいる

# Tasks error in Gradle configuration cache
- [Gradle configuration cache](https://docs.gradle.org/current/userguide/configuration_cache.html)はプロジェクトの設定値を使い回すことで2回目以降のタスク実行を爆速にする仕組み 
- 2.0.0-Beta4から`invocation of Task.project at execution time is unsupported`というconfiguration cacheのエラーが出ていた
- configuration cacheに対応していないタスクがあることで発生している
- Gradleチームが解決に取り組み中

# Support in IntelliJ IDEA

- IntelliJ IDEA 2024.1から使える
- Android StudioはKoalaから使える
- Settings | Languages & Frameworks | Kotlin > Enable K2 Kotlin Modeのチェックボックスをいれる

# Kotlin/JVM
## Generate lambda functions using invokedynamic

- `invokedynamic`がラムダ関数のインスタンス化のデフォルトになった
- `invokedynamic`はKotlin 1.5でcompiler flag(`-Xlambdas=indy`)を設定すると使えた
- 従来のラムダ関数の匿名クラスのインスタンス化よりバイナリサイズが減少する
- `invokedynamic`は現状いくつかの制限がある
    - 生成された匿名クラスのインスタンスはシリアライズできない
    - [`reflect()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect.jvm/reflect.html)メソッドが対応していない
    - `toString()`が読みづらい
- `@JvmSerializableLambda`をつけると個別に以前と同じ挙動にできる
- `-Xlambdas=class`を設定すると全体を以前と同じ挙動にできる


## The kotlinx-metadata-jvm library is now Stable

- kotlinx-metadata-jvmが安定版になった
- kotlinx-metadata-jvmは`@Metadata`を読み取ることで、kotlin-reflectなしで黒魔術を使いやすくするライブラリ
- 安定版になったことで`kotlin-metadata-jvm`(x抜き)でartifactを取得できるようになった

# Kotlin/Native
## Resolving conflicts with Objective-C methods

- Obj-Cメソッドの衝突が解消された
- Obj-Cは同引数異名のメソッドを定義できるがKotlin上ではoverloadエラーが発生していた
- Kotlin 2.0で`@ObjCSignatureOverride`アノテーションが導入された
- `@ObjCSignatureOverride`を付与すると衝突するoverloadを無視するようになる

## Changed log level for compiler arguments

- K/Nの`compile`, `link`, `cinterp`タスクのデフォルトログレベルがINFOからDEBUGに変更された

# Kotlin/Wasm
## Unsigned primitive types in functions with @JsExport

- `@JsExport`を使ってexportした関数で符号無しのPrimitiveな型が使えるようになった

## Binaryen available by default in production builds

- [Binaryen](https://github.com/WebAssembly/binaryen)はWASMの最適化ライブラリ
- プロダクションビルドで設定無しで使えるようになった
- 開発ビルドでは適用されない


## Generation of TypeScript declaration files in Kotlin/Wasm

- `@JsExport`を付与した関数のTypeScript定義(.d.tsファイル)を生成できるようになった
-  ```kotlin
   kotlin {
     wasmJs {
       binaries.executable()
       browser {}
       generateTypeScriptDefinitions() // これを追加する
     }
   }
   ```

## Support for named export

- `@JsExport`を付与した関数が名前付きでexportされるようになった


```kotlin
@JsExport
fun add(a: Int, b: Int) = a + b
```

```javascript
// Kotlin 1.9以前
import exports from "./index.mjs"

exports.add(10, 10);


// Kotlin 2.0
import { add } from "./index.mjs"

add(10, 10);
```

## withWasm() function is split into JS and WASI variants

- gradleのSourceSet設定時に使用する`withWasm()`関数がDeprecatedになった

```kotlin
kotlin {
    applyHierarchyTemplate {
        // Deprecated
        withWasm()

        // Kotlin 2.0
        withWasmJs()
        withWasmWasi()
    }
}
```

## New functionality to catch JavaScript exceptions

- `try-catch`を使ってJavaScript側のExceptionをcatchできるようになった
- `Throwable`もしくは`JsException`としてcatchすることができる
- catchはできるがcall stackなどの情報はまだ取得できない

## The new exception handling proposal is now supported

- Kotlin/WasmのWebAssembly例外処理の[proposal実装](https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md)が試せるようになった
- compiler flagに`-Xwasm-use-new-exception-proposal`を設定すると使える
- `-Xwasm-use-traps-instead-of-exceptions`など既存の機能とも互換性があるので一緒に使える


# Kotlin/JS
## New compilation target

- Kotlin/JSのcompile target設定方法が新しくなった
- この方法で設定するとES2015 classesとES2015 generatorsが有効になる

```kotlin
// Kotlin 1.9
kotlin {
    js(IR) {
        useEsModules() // Enables ES2015 modules
    }
}

tasks.withType<KotlinJsCompile>().configureEach {
    kotlinOptions {
        useEsClasses = true
    }
}


// Kotlin 2.0
kotlin {
    js {
        compilerOptions {
            target.set("es2015")
        }
    }
}
```

## Suspend functions as ES2015 generators

- [KT-63038 Compilation of suspend functions into ES2015 generators](https://youtrack.jetbrains.com/issue/KT-63038/Compilation-of-suspend-functions-into-ES2015-generators)
- 以前は生成したstate machinesをbundleしていたが代わりにES2015 generatorsを使用するようになった
- 変更によってバンドルサイズが減る

## Passing arguments to the main function

- Main関数に引数を渡せるようになった

```kotlin
kotlin {
    js {
        binary.executable()
        // Deno.argsに引数が格納される
        passAsArgumentToMainFunction("Deno.args")

        // NodeJSの場合は`process.argv`に格納される
        nodejs {
            passProcessArgvToMainFunction()
        }
    }
}
```

## Per-file compilation for Kotlin/JS projects

- ktファイルごとにjsファイルを生成するオプションが追加された
- Kotlin 1.9以前は1つのjsファイルにバンドルするかモジュール単位でjsファイルを生成するオプションがあった
- モジュール単位でも大きいjsファイルになる可能性があるためKotlin 2以降はktファイルごとjsファイルを生成することができるようになった
- ktファイルにexport宣言が含まれている場合はktファイルごとに2つのjsファイルが生成される
- compiler optionに`-Xir-per-file`を設定するかgradle.propertiesに`kotlin.js.ir.output.granularity=per-file`を設定すると使える

## Improved collection interoperability

- KotlinのSet, Map, ListなどのCollectionをexportできるようになった
- JavaScriptからKotlinのCollectionを作成することはまだできない

```kotlin
@JsExport
data class User(
    val name: String,
    val friends: List<User> = emptyList()
)

@JsExport
val me = User(
    name = "Me",
    firends = listOf(User(name = "Kodee"))
)
```

```js
import { User, me, KtList } from "my-module"

const allMyFriendNames = me.friends
  .asJsReadonlyArrayView()
  .map(x => x.name)
```

## Support for createInstance()

- JVMのみで使用できたkotlin-reflectの[`createInstance`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect.full/create-instance.html)がKotlin/JSで使用できるようになった

## Support for type-safe plain JavaScript objects

- 型安全なJavaScriptオブジェクトがサポートされた
- `js()`関数でJavaScriptオブジェクトを使用すると実行時エラーもしくは一歳動かないが`@JsPlainObject`を付与したinterfaceを使用することでコンパイル時にエラーを検知できるようになる
- [`js-plain-objects` plugin](https://github.com/JetBrains/kotlin/tree/master/plugins/js-plain-objects)を使用すると使える
- `js-plain-objects` pluginはK2のみをサポートしている
- `js-plain-objects`はinvoke関数とcopy関数を追加する


## Support for npm package manager

- Kotlin 1.9までは[Yarn](https://yarnpkg.com/)のみが使用できた
- gradle.propertiesを設定すると[NPM](https://www.npmjs.com/)を使用することができる

```properties
kotlin.js.yarn=false
```

# Gradle improvements
## New Gradle DSL for compiler options in multiplatform projects

- Multiplatformプロジェクトでcompiler optionを一括設定できるようになった
- Kotlin 1.9以前ではTask, Compiler, SourceSetごとにしか設定できなかった
- Projectレベル、Targetレベル、Taskレベルの順に適用される（そのためProjectレベルで設定したオプションをTargetレベル、Taskレベルで上書きできる）


```kotlin
kotlin {
    // Kotlin 2から使用できるようになった
    compilerOptions {
        allWarningsAsErrors.set(true)
    }
    jvm {
        compilerOptions {
            // `allWarningsAsErrors`と`noJdk`がJVMソースセットに適用される
            noJdk.set(true)
        }
    }

    tasks.named<KotlinJvmCompile>("compileKotlinJvm") {
        compilerOptions {
            // `allWarningsAsErrors`,`noJdk`,`verbose`がcompilerに適用される
            verbose = true
        }
    }
}
```

## New Compose compiler Gradle plugin

- Jetpack Compose ComiplerがKotlinリポジトリに移管された
- [Jetpack Compose compiler moving to the Kotlin repository](https://android-developers.googleblog.com/2024/04/jetpack-compose-compiler-moving-to-kotlin-repository.html)
- 今までは新しいKotlinがリリースされてもcompose comiplerが対応していないためcompose compilerが新しいKotlinに対応するまで待つ必要があったが待たなくてよくなる 

| before | after |
| --- | --- |
| androidx.compose.compiler:compiler | org.jetbrains.kotlin:kotlin-compose-compiler-plugin-embeddable |
| androidx.compose.compiler:compiler-hosted | org.jetbrains.kotlin:kotlin-compose-compiler-plugin |

```kotlin
// Kotlin 1.9
plugin {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
}

// android{}内でcomposeの設定を行う
android {
    buildFeatures {
        compose = true
    }
    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.13"
    }
}

// Kotlin 2以降
plugin {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("org.jetbrains.kotlin.plugin.compose")
}

// topレベルのcomposeCompiler{}内でcomposeの設定を行う
composeCompiler {
    enableStrongSkippingMode = true
}
```

## New attribute to distinguish JVM and Android published libraries

- JVMとandroid向けのライブラリを区別するattributeが全てのvariantで公開されるようになった
  - `android`, `standard-jvm`, `no-jvm`の3種類がある
- JavaプロジェクトでJVM対応されているKMPライブラリを安全に使用できるようになった
- gradle.propertiesに`kotlin.publishJvmEnvironmentAttribute=false`を設定すると無効化できる

## Improved Gradle dependency handling for CInteropProcess in Kotlin/Native

- Kotlin/Nativeでcinteropを使用する際のdefFile生成タスク周りが整理された
- Kotlin 1.9以前ではcinteropタスクで使用するdefFileが別のタスクの成果物であった場合、Gradleタスクの依存を設定して解決する必要があった
- Kotlin 2ではGradleの新しいプロパティである`RegularFileProperty`を使用してdefFileを参照するようになった
- `RegularFileProperty`を使用するとGradleはプロパティを遅延評価するようになるため別タスクの実行を待った上でcinteropタスクが実行されるようになる

```kotlin
kotlin {
    macosArm64("native") {
        compilations.getByName("main") {
            // Kotlin 1.9
            cinterop.create("cinterop-library") {
                defFileProperty.set(createDefFileTask.flatMap { it.defFile.asFile })
                project.tasks.named(interopProcessingTaskName).configure {
                    dependsOn(createDefFileTask)
                }
            }

            // Kotlin 2
            cinterop.create("cinterop-library") {
                definitionFile.set(project.file("def-file.def"))
            }
        }
    }
}
```

## Visibility changes in Gradle

- Kotlin DSLを使用する際に適切にDSLを使用していない場合Warningログが表示されるようになった

```kotlin
kotlin {
    // ここで`KotlinTargetContainerWithPresetFunctions.jvm()`を呼ぶべき
    jvm()

    sourceSets {
        // `NamedDomainObjectContainer<KotlinSourceSet>.jvm()`は存在しないが`KotlinTargetContainerWithPresetFunctions.jvm()`を呼べてしまう
        // Kotlin 2以降はWarningが表示される
        jvm()
    }
}
```


## New directory for Kotlin data in Gradle projects

- Kotlin Gradle Pluginが`<project-root>/.kotlin`配下にcacheを保存するようになった
- gradle.propertiesを設定することで保存先と保存の有無を設定できる

```properties
kotlin.project.persistent.dir=<project-root-directory>/.kotlin # 保存先を変更できる
kotlin.project.persistent.dir.gradle.disableWrite=true # 保存を無効にする
```


## Kotlin/Native compiler downloaded when needed

- Kotlin 1.9以前ではProjectにKotlin/Nativeターゲットが追加されているとconfigurationフェーズでKotlin Native Compilerがダウンロードされていた
  - `~/.konan`などにダウンロードされる
- Kotlin/Navitveターゲットが設定されているがKotlin/Nativeコンパイルを行わない場合もダウンロードされていた
  - ex)iOSターゲットが設定されているプロジェクトをLinuxマシンで開いた場合にもLinux向けのKotlin Native Compilerがダウンロードされてしまっていた
  - CI上などでネットワーク、ディスクリソースを浪費していた
- Kotlin 2では実際にKotlin/Nativeコンパイルを実行するタイミングでダウンロードされるようになる
- `gradle.properties`に`kotlin.native.toolchain.enabled=false`を設定すると以前の挙動に戻せる


## Deprecating old ways of defining compiler options

- `HasCompilerOptions`の`compilerOptions`がdeprecatedになった
- `HasCompilerOptions`interfaceを用いて各DSLにcompipler optionを設定する方法が提供されていたがKotlinコンパイルタスクと同一の`compilerOptions`を提供するため混乱を招いていた
- `New Gradle DSL for compiler options in multiplatform projects`もこれの一環
- 各設定方法が[ドキュメント](https://kotlinlang.org/docs/gradle-compiler-options.html)にあるのでそちらを読んで改めて設定するとよい

## Bumped minimum AGP supported version

- Kotlin 2.0.0以降はAGP7.1.3以上である必要がある


## New Gradle property to try latest language version

- 新しいKotlinバージョンを試すためのオプションが追加された
- gradle.propertiesに`kotlin.experimental.tryNext=true`を設定すると新しいKotlinバージョンを試せる
- Kotlin2.0のプロジェクトでオプションを設定するとKotlin2.1が使用できる


## New JSON output format for build reports

- Kotlin 1.7でビルドのレポートをファイル形式で保存することができるようになった
- txtのみサポートされたいたがjson形式が新たに加わった

# Standard library
## Stable replacement of the enum class values generic function

- `enumEntries<T>()`がstableになった
- `enumEntries<T>()`は`enumValues<T>()`を代替する関数
- Kotlin 1.8.20で導入された`Enum.entries`と`Enum.values()`の関係と同じく, `enumEntries<T>()`のほうがパフォーマンスが良いため置き換えることが推奨される


## Stable AutoCloseable interface

- [`AutoCloseable`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-auto-closeable/)は`java.lang.AutoCloseable`のKotlin版
- `try-with-resource`をKotlinで実現するinterface
- 実装しているクラスは[`use`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/use.html)関数などを用いて適切にresource解放する実装ができる

## Common protected property AbstractMutableList.modCount

- [`AbstractMutableList.modCount`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-abstract-mutable-list/mod-count.html)がcommonコードで使用できるようになった
- Kotlin 1.9以前では各Platformで実装されていたためcommonコードで使用できなかった

## Common protected function AbstractMutableList.removeRange

- [`AbstractMutableList.removeRange`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-abstract-mutable-list/remove-range.html)がcommonコードで使用できるようになった
- Kotlin 1.9以前では各Platformで実装されていたためcommonコードで使用できなかった

## Common String.toCharArray(destination)

- jvmコードでのみ使用可能だった[`String.toCharArray(destination)`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/to-char-array.html)がcommonコードで使用できるようになった
- `String.toCharArray()`は新しいCharArrayのインスタンスを生成するが、`String.toCharArray(destination)`は生成しない