Kotlin 1.7.0の変更点

※ソース記事は[こちら](https://kotlinlang.org/docs/whatsnew17.html)
※Kotlin/JS、Kotlin/Nativeについては割愛します。

Kotlin 1.7.0がリリースされた。新しいKotlin/JVMのK2コンパイラのアルファバージョンが明らかになり、言語機能が安定化され、JVM、JS、Nativeプラットフォームのための性能改善がもたらされている。
こちらにこのバージョンの主な更新の一覧がある。
- 現在、新しいKotlin K2コンパイラがアルファであり、それにより重大な性能改善が提供されている。それはJVMのみで利用可能であり、kaptを含めどのコンパイラプラグインとも連携しない。
- Gradleでの差分コンパイルの新しい取り組み。差分コンパイルは、今ではKotlinでない独立したモジュール内で起きた変更もサポートしており、Gradleと互換性がある。
- オプトインが必要なアノテーション、明らかな非null型、ビルダーインターフェイスが安定化された。
- 型引数のためのアンダースコア演算子が今では存在する。他の型が指定されると、自動的に引数の型が推論されるときに使用することができる。
- このリリースではインラインクラスのインライン値に対するdelegateによる実装ができるようになった。今では多くのケースでメモリを割り当てない軽量なラッパーを作ることができる。

このビデオで変更の短い概要を見ることができる。

https://youtu.be/54WEfLKtCGk

# JVMのための新しいKotlin K2コンパイラがアルファ
今回のKotlinリリースでは、新しいKotlin K2コンパイラの**アルファ**バージョンが導入されている。新しいコンパイラは新しい言語機能の開発を加速し、Kotlinがサポートするすべてのプラットフォームを統一し、性能を改善し、コンパイラ拡張のためにAPI提供することを目的としている。
新しいコンパイラのいくつかの詳しい説明とその利点がすでに公開されている。
- [新しKotlinコンパイラへの道](https://www.youtube.com/watch?v=iTdJJq_LyoY)
- [K2コンパイラ：上方からの視点](https://www.youtube.com/watch?v=db19VFLZqJM)

注目すべきは、新しいK2コンパイラのアルファバージョンでは、主に性能改善にフォーカスされており、JVMプロジェクトとのみ連携するということが重要である。Kotlin/JS、Kotlin/Native、その他のマルチプラットフォームプロジェクトはサポートされず、[kapt](https://kotlinlang.org/docs/kapt.html)を含むコンパイラプラグインのどれとも動作しない。
ベンチマークでは、内部のプロジェクトにおいて、並外れた結果を示している。
| プロジェクト | 現在のKotlinコンパイラ性能 | 新しいK2コンパイラ性能 | 性能増加 |
|:-:|:-:|:-:|:-:|
| Kotlin  | 2.2KLOC/s  | 4.8KLOCK/s  | ~x2.2  |
| You Track  | 1.8KLOC/s  | 4.2KLOC/s  | ~x2.3  |
| IntelliJ IDEA  | 1.8KLOC/s  | 3.9KLOC/s  | ~x2.2  |
| Space  | 1.2KLOC/s  | 2.8KLOC/s  | ~x2.3  |

:::note info
KLOC/s性能値は、コンパイラが秒間に処理する千行の数を意味する。
:::

自分のJVMプロジェクトについて性能増加を調べ、古いコンパイラの結果と比較することができる。Kotlin K2コンパイラを有効にするには、次のコンパイラオプションを使うこと。
```
-Xuse-k2
```
さらに、K2コンパイラは[多くのバグフィックスを含んでいる。](https://youtrack.jetbrains.com/issues/KT?q=tag:%20fixed-in-frontend-ir%20sort%20by:%20Priority,%20votes,%20updated)この一覧から、**オープン状態**の問題でさえ、K2では実は修正されていることに注意してほしい。
次のKotlinのリリースではK2コンパイラの安定性が向上し、多くの機能が提供される予定であるので、期待していただき、フィードバックを提供いただきたい。
# 言語
Kotlin 1.7.0では、delegateによる実装と、型引数のための新しいアンダースコア演算子が導入されている。以前のリリースでプレビューとして導入されたいくつかの言語機能も安定化されている。
## インラインクラスのインライン値へのdelegateによる実装
値あるいはクラスインスタンスに対する軽量なラッパーを作りたいとき、手動ですべてのインターフェイスメソッドを実装する必要がある。delegateによる実装により、この問題が解決するが、1.7.0より前では、インラインクラスとは連携しなかった。この制限は削除され、今では多くのケースでメモリを割り当てずに軽量なラッパーを作ることができる。
```Kotlin
interface Bar {
    fun foo() = "foo"
}

@JvmInline
value class BarWrapper(val bar: Bar): Bar by bar

fun main() {
    val bw = BarWrapper(object: Bar {})
    println(bw.foo())
}
```
## 型引数のためのアンダースコア演算子
Kotlin 1.7.0では型引数のためのアンダースコア`_`演算子が導入されている。他の型が指定されると、自動的に型引数を推論させるために使うことができる。
```Kotlin
abstract class SomeClass<T> {
    abstract fun execute(): T
}

class SomeImplementation : SomeClass<String>() {
    override fun execute(): String = "Test"
}

class OtherImplementation : SomeClass<Int>() {
    override fun execute(): Int = 42
}

object Runner {
    inline fun <reified S: SomeClass<T>, T> run(): T {
        return S::class.java.getDeclaredConstructor().newInstance().execute()
    }
}

fun main() {
    // TはSomeImplementationがSomeClass<String>から継承されているため、Stringと推論される
    val s = Runner.run<SomeImplementation, _>()
    assert(s == "Test")

    // TはOtherImplementationがSomeClass<Int>から継承されいているため、Intと推論される
    val n = Runner.run<OtherImplementation, _>()
    assert(n == 42)
}
```
::: note
アンダースコア演算子は型引数を推論するための変数リストのどの位置でもを使うことができる。
:::
## ビルダー推論の安定化
ビルダー推論とは、ジェネリックなビルダー関数を呼ぶときに役立つ、ある特別な種類の型推論である。これは、コンパイラが関数呼び出しの型引数を推論するのを助ける。型推論には、その関数が引数で受け取るラムダ式内部での別の関数呼び出しの型情報が用いられる。

1.7.0から、[1.6.0で導入された](https://kotlinlang.org/docs/whatsnew16.html#changes-to-builder-inference)、`-Xenable-builder-inference`コンパイラオプションを指定しなくても、通常の型推論では型についての十分な情報が得られない場合は自動で有効化される。
[カスタムジェネリクスビルダーの書き方を学ぶ](https://kotlinlang.org/docs/using-builders-with-builder-inference.html)
## オプトイン必要物の安定化
[オプトイン必要物](https://kotlinlang.org/docs/opt-in-requirements.html)は、今では[Stable](https://kotlinlang.org/docs/components-stability.html)であり、追加のコンパイラ構成は必要ない。
1.7.0より前は、オプトイン機能自体は、警告を避けるため、`-opt-in=kotlin.RequiresOptIn`引数が必要だった。もはやこれは必要ないが、[モジュールレベル](https://kotlinlang.org/docs/opt-in-requirements.html#module-wide-opt-in)の他のアノテーションのため、`opt-in`コンパイラ引数はまだ使うことができる。
## 明らかな非null型の安定化
Kotlin 1.7.0では明らかな非null型は[Stable](https://kotlinlang.org/docs/components-stability.html)に昇格になった。これはジェネリクス型のJavaクラスとインターフェイスを拡張するときに、より相互運用性を提供する。
ジェネリクスの型パラメータを使う側で、`T & Any`という新しい文法で、明らかな非nullとしてマークをつけることができる。構文の型は[インターセクション型](https://en.wikipedia.org/wiki/Intersection_type)のための表記法に由来しており、現在は、`&`の左側のnullableな上方境界と、右側の非nullな`Any`を持つ型パラメータに限定されている。
```Kotlin
fun <T> elvisLike(x: T, y: T & Any): T & Any = x ?: y

fun main() {
    // OK
    elvisLike<String>("", "").length
    // Error: 'null' は非null型の値ではない
    elvisLike<String>("", null).length

    // OK
    elvisLike<String?>(null, "").length
    // Error: 'null'  は非null型の値ではない
    elvisLike<String?>(null, null).length
}
```
[こちらのKEEP](https://github.com/Kotlin/KEEP/blob/c72601cf35c1e95a541bb4b230edb474a6d1d1a8/proposals/definitely-non-nullable-types.md)で明らかな非null型についての知識を深める
# Kotlin/JVM
今回のリリースでは、Kotlin/JVMコンパイラと新しいコンパイラオプションのための性能改善がもたらされている。さらに関数型インターフェイスのコンストラクタに対する関数参照がStableになっている。留意すべきは、1.7.0からKotlin/JVMのコンパイルのデフォルトバージョンが現在`1.8`だということである。
## コンパイラ性能の最適化
Kotlin 1.7.0ではKotlin/JVMコンパイラのための性能改善が導入されている。ベンチマークによると、コンパイル時間はKotlin 1.6.0に比較して[平均で10%削減された](https://youtrack.jetbrains.com/issue/KT-48233/Switching-to-JVM-IR-backend-increases-compilation-time-by-more-t#focus=Comments-27-6114542.0-0)。例えば[`kotlinx.html`を使うプロジェクト](https://youtrack.jetbrains.com/issue/KT-51416/Compilation-of-kotlinx-html-DSL-should-still-be-faster)のようにインライン関数を多用するプロジェクトでは、バイトコードの後処理の改善のおかげでコンパイルが早くなるだろう。
## 新しいコンパイラオプション：-Xjdk-release
Kotlin 1.7.0では`-Xjdk-release`新しいコンパイラオプションが提供されている。このオプションは[javacの
コマンドラインオプション`--release`](http://openjdk.java.net/jeps/247)に似ている。`-Xjdk-release`オプションはターゲットのバイトコードバージョンを制御し、指定したJavaバージョンに対するクラスパスでのJDKのAPIを制限する。例えば、依存性の中のJDKがバージョン9以上であっても、`kotlinc -Xjdk-release=1.8`は、`Java.lang.Module`を参照することは許可されない。

:::note
このオプションはOpenJDKディストリビューションでのみ動作する。
:::

どうかフィードバックを[こｎYou Trackチケット](https://youtrack.jetbrains.com/issue/KT-29974/Add-a-compiler-option-Xjdk-release-similar-to-javac-s-release-to)で残してもらいたい。
## 関数型インターフェイスのコンストラクタに対する関数参照の安定化
関数型インターフェイスのコンストラクタに対する[関数参照](https://kotlinlang.org/docs/reflection.html#callable-references)は、現在[Stable](https://kotlinlang.org/docs/components-stability.html)である。コンストラクタ関数をもつインターフェイスから、関数参照を使う関数型インターフェイスへの[移行](https://kotlinlang.org/docs/fun-interfaces.html#migration-from-an-interface-with-constructor-function-to-a-functional-interface)方法を学ぶことができる。
どうか何か問題をみつけたら、[You Track](https://youtrack.jetbrains.com/newissue?project=kt)で報告していただきたい。
## JVMターゲットバージョン1.6の削除
Kotlin/JVMコンパイルのデフォルトターゲットバージョンは、`1.8`である。`1.6`ターゲットは削除された。
どうかJVMターゲットバージョンを1.8かそれ以上に移行していただきたい。JVMターゲットバージョンを更新する方法を次で学ぶことができる。
- [Gradle](https://kotlinlang.org/docs/gradle.html#attributes-specific-to-jvm)
- [Maven](https://kotlinlang.org/docs/maven.html#attributes-specific-to-jvm)
- [コマンドラインコンパイラ](https://kotlinlang.org/docs/compiler-reference.html#jvm-target-version)
# 標準ライブラリ
Kotlin 1.7.0では、標準ライブラリには幅広い変更と改善が届けられた。それらには新しい機能が導入、実験的な機能の安定化、Native/JS/JVMのための名前付きキャプチャグループのサポートの統一が、挙げられる。
## min()、max()コレクション関数が非nullを返却
Kotlin 1.4.0で、`min()`、`max()`コレクション関数が`minOrNull()`、`maxOrNull()`に改名された。これらの新しい名前は、その振る舞い-もしレシーバーのコレクションが空の場合はnullを返却する-をより反映している。それはKotlinのコレクションAPI中で使われている命名規則を持った関数のふるまいを揃えることにも役立った。
同様のことが、`minBy()`、`maxBy()`、`minWith()`、`maxWith()`についても当てはまり、それらすべてはKotlin 1.4.0で*OrNull()のシノニムを得た。この変更の影響を受けた古い方の関数は次第に非推奨となった。
Kotlin 1.7.0では、オリジナルの関数名を再導入したが、非nullの戻り値型を持つ。新しい`min()`、`max()`、`minBy()`、`maxBy()`、`minWith()`、`maxWith()`関数は、今では厳密にコレクション要素を返却するか、例外をスローする。
```Kotlin
fun main() {
    val numbers = listOf<Int>()
    println(numbers.maxOrNull()) // "null"
    println(numbers.max()) // "Exception in... Collection is empty."
}
```
## 指定したインデックスでの正規表現マッチング
`Regex.matchAt()`と`Regex.matchesAt()`関数は、[1.5.30で導入され](https://kotlinlang.org/docs/whatsnew1530.html#matching-with-regex-at-a-particular-position)、現在Stableである。それらにより、正規表現が`String`か`CharSequence`内で特定の位置でちょうどマッチしたかどうかをチェックする方法が提供される。
`matchesAt()`はマッチのチェックをし、booleanの結果を返却する。
```Kotlin
fun main() {
    val releaseText = "Kotlin 1.7.0 is on its way!"
    // 正規表現: 1桁数字、ドット、1桁数字、ドット、1桁以上の数字
    val versionRegex = "\\d[.]\\d[.]\\d+".toRegex()

    println(versionRegex.matchesAt(releaseText, 0)) // "false"
    println(versionRegex.matchesAt(releaseText, 7)) // "true"
}
```
`matchAt()`はみつかったらマッチしたもの、そうでない場合は`null`を返却する。
```Kotlin
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"
}
```
この[You Track問題](https://youtrack.jetbrains.com/issue/KT-34021)でフィードバックをいただければありがたい。
## 以前の言語とAPIバージョンの延長サポート
幅広い以前のKotlinバージョンで消費する予定のライブラリを開発しているライブラリ開発者をサポートするため、メジャーなKotlinリリースの頻度増加に対応するため、以前の言語とAPIバージョンのためのサポートを延長した。
Kotlin 1.7.0では、2ではなく3つ前の言語とAPIバージョンがサポートされている。これはKotlin 1.7.0では1.4.0までのKotlinバージョンをターゲットにするライブラリの開発をサポートすることを意味する。後方互換性についてのより情報を得るには、[Compatibilityモード](https://kotlinlang.org/docs/compatibility-modes.html)を参照のこと。
## リフレクション経由でのアノテーションへのアクセス
[`KAnnotatedElement.findAnnotations()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect.full/find-annotations.html)拡張関数は、最初に[1.6.0で導入された](https://kotlinlang.org/docs/whatsnew16.html#repeatable-annotations-with-runtime-retention-for-1-8-jvm-target)が、現在は[Stable](https://kotlinlang.org/docs/components-stability.html)である。この[リフレクション](https://kotlinlang.org/docs/reflection.html)関数は、個別に適用されたものと、繰り返しアノテーションを含む、要素についての与えられた型のすべてのアノテーションを返却する。
```Kotlin
@Repeatable
annotation class Tag(val name: String)

@Tag("First Tag")
@Tag("Second Tag")
fun taggedFunction() {
    println("I'm a tagged function!")
}

fun main() {
    val x = ::taggedFunction
    val foo = x as KAnnotatedElement
    println(foo.findAnnotations<Tag>())
    // [@Tag(name=First Tag), @Tag(name=Second Tag)]
}
```
## 安定した深い再帰的な関数
深い再帰的な関数は、[Kotlin 1.4.0](https://blog.jetbrains.com/kotlin/2020/07/kotlin-1-4-rc-debugging-coroutines/#Defining_deep_recursive_functions_using_coroutines)から、実験的機能として利用可能で、Kotlin 1.7.0で今では[Stable](https://kotlinlang.org/docs/components-stability.html)である。`DeepRecursiveFunction`を使うことで、実際の呼び出しスタックを使う代わりに、ヒープ上のスタックを保持する関数を定義することができる。これにより、非常に深い再帰的な演算を実行することが可能になる。深い再帰的な関数を呼び出すには、それを`Invoke`する。
この例では、深い再帰的な関数はが、二分木の深さを計算するために使われている。このサンプル関数は、たとえ自分自身を再帰的に100,000回呼び出したとしても、`StackOverFlow`がスローされることはない。
```Kotlin
class Tree(val left: Tree?, val right: Tree?)

val calculateDepth = DeepRecursiveFunction<Tree?, Int> { t ->
    if (t == null) 0 else maxOf(
        callRecursive(t.left),
        callRecursive(t.right)
    ) + 1
}

fun main() {
    // 100_000の深さを持つ木を生成する
    val deepTree = generateSequence(Tree(null, null)) { prev ->
        Tree(prev, null)
    }.take(100_000).last()

    println(calculateDepth(deepTree)) // 100000
}
```
コードの中で、1000回を超える深さの再帰呼び出しには深い再帰的な関数を使うことを検討すること。
## デフォルトのタイムソースのためのインラインクラスに基づくタイムマーク
Kotlin 1.7.0では`TimeSource.Monotonic`によって返却されるタイムマークをインラインの値クラスに変更することにより、時間計測の機能の性能が向上している。これは`markNow()`、`elapsedNow()`、`measureTime()`、`measureTimedValue()`のように、関数を呼び出すことを意味しており、`TimeMark`インスタンスのためにラッパークラスを割り当てない。特に、ホットパスの一部であるコード断片を計測するとき、これにより、計測の性能上のインパクトを最小化してくれる。
```Kotlin
@OptIn(ExperimentalTime::class)
fun main() {
    val mark = TimeSource.Monotonic.markNow() // 返却される`TimeMark`はインラインクラス
    val elapsedDuration = mark.elapsedNow()
}
```
::: note
この最適化は、`TimeMark`が取得される元のタイムソースが、`TimeSource.Monotonic`として静的に知られるときのみ、利用可能である。
:::

## JavaのOptionalのための新しい実験的関数
Kotlin 1.7.0では、Javaの`Optional`クラスとの連携を簡単にする、新しい便利な関数が登場している。これらの新しい関数により、JVM上でオプショナルなオブジェクトをアンラップ、変換するために使うことができ、Java APIとより簡潔に連携することができる。
`getOrNull()`、`getOrDefault()`、`getOrElse()`拡張関数により、もし存在する場合、`Optional`の値を取り出すことができる。それ以外は、デフォルト値、`null`、関数により返却される値がそれぞれ得られる。
```Kotlin
val presentOptional = Optional.of("I'm here!")

println(presentOptional.getOrNull())
// "I'm here!"

val absentOptional = Optional.empty<String>()

println(absentOptional.getOrNull())
// null
println(absentOptional.getOrDefault("Nobody here!"))
// "Nobody here!"
println(absentOptional.getOrElse {
    println("Optional was absent!")
    "Default value!"
})
// "Optional was absent!"
// "Default value!"
```
`toList()`、`toSet()`、`asSequence()`拡張関数は、存在する`Optional`の値をリスト、セット、シーケンス、それ以外は空のコレクションを返却する。`toCollection()`拡張関数は、`Optional`の値をすでに存在する対象のコレクションに追加する。
```Kotlin
val presentOptional = Optional.of("I'm here!")
val absentOptional = Optional.empty<String>()
println(presentOptional.toList() + "," + absentOptional.toList())
// ["I'm here!"], []
println(presentOptional.toSet() + "," + absentOptional.toSet())
// ["I'm here!"], []
val myCollection = mutableListOf<String>()
absentOptional.toCollection(myCollection)
println(myCollection)
// []
presentOptional.toCollection(myCollection)
println(myCollection)
// ["I'm here!"]
val list = listOf(presentOptional, absentOptional).flatMap { it.asSequence() }
println(list)
// ["I'm here!"]
```
これらの拡張関数は、Kotlin 1.7.0でExperimentalとして導入されている。[このkEEP](https://github.com/Kotlin/KEEP/pull/291)で`Optional`拡張関数についてより学ぶことができる。いつも通り、[Kotlin issue tracker](https://kotl.in/issue)でフィードバックを歓迎している。
# Gradle
このリリースでは、新しいビルドレポート、Gradleプラグインバリアントのサポート、kaptにおける新しい統計などが、導入されている。
## 差分コンパイルの新しいアプローチ
::: note alert
差分コンパイルの新しいアプローチは、[Experimental](https://kotlinlang.org/docs/components-stability.html)である。それはいつでも削除され、変更されるかもしれない。オプトインが必要(詳細は後述)である。評価目的でのみ使用することをおすすめし、[You Track](https://youtrack.jetbrains.com/issues/KT)でのフィードバックをいただければありがたい。
:::

Kotlin 1.7.0では、モジュールをまたがった変更のための差分コンパイルが、作り直された。今では差分コンパイルは、依存するKotlinではないモジュール内部の変更でもサポートされ、コンパイルを避けるための、[Gradleビルドキャッシュ](https://docs.gradle.org/current/userguide/build_cache.html)のサポートとの互換性も改善された。
ビルドキャッシュを使うか、非KotlinのGradleモジュールを頻繁に変更する場合に新しいアプローチの最も重大な利点が実感できると考えている。`kotlin-gradle-plugin`モジュール上でのKotlinのためのテストでは、キャッシュヒットの後で変更のため、80%以上の改善が見られた。
新しいアプローチを試すには、`gradle.properties`に次のオプションをセットすること。
```
kotlin.incremental.useClasspathSnapshot=true
```
::: note
差分コンパイルについての新しいアプローチは、現在GradleビルドシステムにおけるJVMバックエンドでのみ利用可能である。
:::

計画では、この技術を安定化させ、他のバックエンド(例えばJS)とビルドシステム用のサポートを追加することである。このコンパイルの仕組みでの問題や、おかしなふるまいがあれば、[You Track](https://youtrack.jetbrains.com/issues/KT)で報告をいただけると幸いである。
Kotlinチームは、[Ivan Gavrilovic](https://github.com/gavra0)、[Hung Nguyen](https://github.com/hungvietnguyen)、[Cédric Champeau](https://github.com/melix)、その他外部の貢献者の助けに大変感謝している。
## Kotlinコンパイラタスクのためのビルドレポート
::: note alert
Kotlinビルドレポートは、[Experimental](https://kotlinlang.org/docs/components-stability.html)である。それはいつでも削除され、変更されるかもしれない。オプトインが必要(詳細は後述)である。評価目的でのみ使用することをおすすめし、[You Track](https://youtrack.jetbrains.com/issues/KT)でのフィードバックをいただければありがたい。
:::

Kotlin 1.7.0ではコンパイル性能を追跡するのに役立つビルドレポートが導入されている。レポートには、異なるコンパイルフェーズの時間と、コンパイルが差分にできなかった理由が含まれる。
ビルドレポートはコンパイルタスクの問題を調査したいときに役に立つ。例えば。
- Gradleビルドが長い時間かかり、ひどい性能の根本原因を理解したいとき。
- 同じプロジェクトでのコンパイル時間が異なる、あるときは数秒かかり、ある時は数分かかるとき。

ビルドレポートを有効にするには、`gradle.properties`内でビルドレポートの出力先を宣言する。
```
kotlin.build.report.output=file
```
次の値(とその組み合わせ)が可能である。
- `file`はローカルファイルにビルドレポートを保存する
- `build_scan`は、[build scan](https://scans.gradle.com/)の`カスタム値`セクションにビルドレポートを保存する。
::: note 
Gradle Enterprise プラグインではカスタム値の数とその長さが制限されている。大きなプロジェクトではいくつかの値は失われることがありうる。
:::

- `http`はHTTP(S)を使ってビルドレポートをPOSTする。POSTメソッドはJSON形式でメトリクスを送信する。データはバージョンごとに異なるかもしれない。[Kotlinリポジトリ](https://github.com/JetBrains/kotlin/blob/master/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/CompileStatisticsData.kt)に送信されるデータの現在のバージョンを見ることができる。

長時間動作するコンパイルのためビルドレポートを分析することで解決できる、二つの一般的なケースがある。
- ビルドが差分でなかった。原因を分析し、潜在的な問題を解決すること。
- ビルドは差分だったが、時間がかかりすぎた。ソースファイルを再編成することを試みること。大きなファイルを分割したり、異なるファイルにクラスを分割して保存したり、大きなクラスをリファクタリングしたり、異なるファイルにトップレベル関数を宣言したり等々。

自分のインフラでビルドレポートを自由に使ってかまわない。もしフィードバックがあるか、何か問題にぶつかるか、改善を提案したい場合は、どうか躊躇なく[issue tracker](https://youtrack.jetbrains.com/newIssue)に報告していただきたい。
## 最低サポートバージョンのバージョンアップ
Kotlin 1.7.0から、最低のサポートGradleバージョンは6.7.1である。[Gradleプラグインバリアント](https://docs.google.com/document/d/1tOacnL6-ef8oVIWV0hUynvXq5zqadkTOadvysMLWF5w/edit#support-for-gradle-plugin-variants)と新しいGradle APIをサポートするために[バージョンを上げる](https://youtrack.jetbrains.com/issue/KT-49733/Bump-minimal-supported-Gradle-version-to-6-7-1)必要があった。将来は、Gradleプラグインバリアントの恩恵により、最低サポートバージョンを頻繁に上げる必要はなくなるはずである。
さらにAndroid Gradleプラグインの最低サポートバージョンも現在は、3.6.4である。

## Gradleプラグインバリアントのサポート
Gradle 7.0ではGradleプラグイン著者のための新しい機能、[バリアントつきプラグイン](https://docs.gradle.org/7.0/userguide/implementing_gradle_plugins.html#plugin-with-variants)が導入された。この機能は、7.1より低いGradleバージョンの互換性を維持しつつ、新しいGradleの機能を簡単にサポートすることが可能である。[Gradleでのバリアント選択](https://docs.gradle.org/current/userguide/variant_model.html)について知識を深める。
Gradleプラグインバリアントにより、異なるGradleプラグインのために、異なるKotlin Gradleプラグインを出荷することができる。Gradleの最古のサポートバージョンに対応する`main`バリアントで、ベースのKotlinコンパイルをサポートすることが目的である。それぞれのバリアントには、対応するリリースからのGradleの機能のための実装が含まれる。最新のバリアントでは、最も広範なGradleの機能セットがサポートされるだろう。このアプローチにより、機能を制限しながら古いGradleバージョンのサポートを拡張することができる。
現在、Kotlin Gradleプラグインには二つのバリアントがある。
- Gradle 6.7.1-6.9.2のための`main`
- Gradle7.0以上のための`gradle70`

将来のKotlinリリースではさらに追加されるかもしれない。
自分のビルドでどのバリアントが使われているか調べるには、[`--info`ログレベル](https://docs.gradle.org/current/userguide/logging.html#sec:choosing_a_log_level)を有効にして`Using Kotlin Gradle plugin`から始まる出力文字列、例えば`Using Kotlin Gradle plugin main variant`、を検索する。

::: note
こちらにGradleにおけるバリアント選択でいくつかの既知の問題の回避策がある。
- [pluginManagement内のResolutionStrategyが複数バリアントを持つプラグインで動作しない](https://github.com/gradle/gradle/issues/20545)  
- [プラグインがbuildSrcの一般依存性として追加されるとプラグインバリアントが無視される](https://github.com/gradle/gradle/issues/20847)
:::

[このYou Trackチケット](https://youtrack.jetbrains.com/issue/KT-49227/Support-Gradle-plugins-variants)でフィードバックを残していただきたい。
## Kotlin Gradleプラグインの変更点
Kotlin GradleプラグインAPI実装はいくつかの改善を受けている。
- ユーザーが構成できる入力を持つ、Kotlin/JVMとKotlin/kaptタスクのための新しいインターフェイス
- すべてのKotlinプラグインが継承する、新しい`KotlinBasePlugin`インターフェイス。任意のKotlin Gradleプラグイン(JVM,JS,マルチプラットフォーム,Native,その他のプラットフォーム)が適用されるときはいつでも、いくつかの構成可能なアクションをトリガーしたいときにこのインターフェイスを使う。
```
project.plugins.withType<org.jetbrains.kotlin.gradle.plugin.KotlinBasePlugin>() {
    // ここにアクションを構成する
}
```
この[You Trackチケット](https://youtrack.jetbrains.com/issue/KT-48008/Consider-offering-a-KotlinBasePlugin)で`KotlinBasePlugin`についてのフィードバックを残すことができる。
- Android Gradleプラグイン内でKotlinコンパイルを構成するために、そのための下地を置いた。それは自分のビルドにKotlin Android Gradleプラグインを追加する必要がないという意味である。追加されたサポートを学び試すため、[Android Gradleプラグインのリリースアナウンス](https://developer.android.com/studio/releases/gradle-plugin)をフォローしてもらいたい。

## sam-with-receiverプラグインがプラグインAPI経由で利用可能
[sam-with-receiverプラグイン](https://kotlinlang.org/docs/sam-with-receiver-plugin.html)が現在、[GradleプラグインDSL](https://docs.gradle.org/current/userguide/plugins.html#sec:plugins_block)で利用可能である。
```
plugins {
    id("org.jetbrains.kotlin.plugin.sam.with.receiver") version "$kotlin_version"
}
```
## コンパイルタスクの変更
コンパイルタスクは、このリリースで多くの変更を受けている。
- Kotlinコンパイルタスクは、もはやGradleの`AbstractCompile`タスクを継承していない。`DefaultTask`のみを継承している。
- `AbstractCompile`タスクは、`sourceCompatibility`と`targetCompatibility`入力を持つ。 `AbstractCompile`タスクはもはや継承されていないので、これらの入力はKotlinのユーザースクリプトでは利用できない。
- `SourceTask.stableSources`入力はもはや利用できず、`source`入力を使わなければならない。`setSource(...)`メソッドはまだ利用できる。
- すべてのコンパイルタスクは、現在、コンパイルに必要なライブラリの一覧のため`libraries`入力を使う。`KotlinCompile`タスクはまだ、非推奨のKotlinプロパティ`classpath`を使用しているが、将来のリリースで削除されるだろう。
- コンパイルタスクは、まだ`PatternFilterable`インターフェイスを実装しており、Kotlinソースをフィルターすることができる。`sourceFilesExtensions`入力は、`PatternFilterable`メソッドを使うために削除された。
- 非推奨の`Gradle destinationDir: File`出力は、`destinationDirectory: DirectoryProperty`出力に置き換えられた。

どうぞ[このYou Trackチケット](https://youtrack.jetbrains.com/issue/KT-32805)でフィードバックを残していただきたい。
## kaptにおけるそれぞれのアノテーションプロセッサで生成されたファイルの統計
`kotlin-kapt`Gradleプラグインは、すでに[それぞれのプロセッサ用に性能統計をレポート](https://github.com/JetBrains/kotlin/pull/4280)している。Kotlin 1.7.0から、それぞれのアノテーションプロセッサ用の生成ファイル数についての統計をレポートすることができる。
これはビルドの一部として不要なアノテーションプロセッサがあるかどうかを追跡するのに役に立つ。生成されたレポートを使い、不要なアノテーションプロセッサを引き起こしているモジュールを探して、それを防ぐためにモジュールを更新することができる。
次の2ステップで統計を有効にする。
- `build.gradle.kts`内で`showProcessorStats`フラグを`true`にセットする。
```
kapt {
    showProcessorStats = true
}
```
- `gradle.properties`内で`kapt.verbose`Graleプロパティを`true`にセットする。
```
kapt.verbose=true
```
::: note
[コマンドラインオプション`verbose`](https://kotlinlang.org/docs/kapt.html#using-in-cli)経由でも冗長出力を有効にすることができる。
:::

統計はログに、`info`レベルで見ることができる。`Annotation processor stats:`行に続くそれぞれのアノテーションプロセッサの実行時間の統計を見ることができる。これらの行の後、`Generated files report:`行に続いて、それぞれのアノテーションプロセッサのために生成されたファイル数の統計が存在する。例えば、
```
[INFO] Annotation processor stats:
[INFO] org.mapstruct.ap.MappingProcessor: total: 290 ms, init: 1 ms, 3 round(s): 289 ms, 0 ms, 0 ms
[INFO] Generated files report:
[INFO] org.mapstruct.ap.MappingProcessor: total sources: 2, sources per round: 2, 0, 0
```
どうぞ[このYou Trackチケット](https://youtrack.jetbrains.com/issue/KT-51132/KAPT-Support-reporting-the-number-of-generated-files-by-each-ann)でフィードバックを残していただきたい。
## kotlin.compiler.execution.strategyシステムプロパティが非推奨
Korlin 1.6.20で[Kotlinコンパイラの実行戦略を定義するための新しいプロパティ](https://kotlinlang.org/docs/whatsnew1620.html#properties-for-defining-kotlin-compiler-execution-strategy)が導入された。Kotlin 1.7.0では新しプロパティのために古い`kotlin.compiler.execution.strategy`システムプロパティの非推奨サイクルが開始された。
`kotlin.compiler.execution.strategy`システムプロパティを使うと、警告を受けるだろう。このプロパティは将来のリリースで削除されるだろう。古いふるまいを保持するには、システムプロパティを同じ名前のGradleプロパティで置き換えること。`gradle.properties`でこれを行うことができる。例えば、
```
kotlin.compiler.execution.strategy=out-of-process
```
コンパイルタスクプロパティ`compilerExecutionStrategy`でも使うことができる。[Graldeのページ](https://kotlinlang.org/docs/gradle.html#defining-kotlin-compiler-execution-strategy)でこれについて知識を深める。
## 非推奨オプション、メソッド、プラグインの削除
###  useExperimentalAnnotationメソッドの削除
Kotlin 1.7.0では、`useExperimentalAnnotation` Gradleメソッドの非推奨サイクルを完了した。モジュール内でAPIを使用するためにオプトインにするには、`optIn()`を使用すること。
例えば、もしGradleモジュールがマルチプラットフォームの場合
```
sourceSets {
    all {
        languageSettings.optIn("org.mylibrary.OptInAnnotation")
    }
}
```
Kotlinにおける[オプトイン要求](https://kotlinlang.org/docs/opt-in-requirements.html)について知識を深める。
### 非推奨のコンパイルオプションの削除
いくつかのコンパイルオプションの非推奨サイクルが完了した。
- `kotlinOptions.jdkHome`コンパイルオプションが1.5.30で非推奨になり、現在のリリースで削除された。Gradleビルドは現在、このオプションが含まれる場合、失敗する。[Javaのツールチェーン](https://kotlinlang.org/docs/whatsnew1530.html#support-for-java-toolchains)の使用を推奨しており、Kotlin 1.5.30からサポートされている。
- 非推奨の`noStdlib`コンパイルオプションも削除された。GradleプラグインはKotlin標準ライブラリが存在するかどうかを制御するために、 `kotlin.stdlib.default.dependency=true`プロパティを使用している。
::: note
コンパイル引数の`-jdkHome`と`-no-stdlib`はまだ利用可能である。
:::

### 非推奨プラグインの削除
Kotlin 1.4.0で、`kotlin2js`、`kotlin-dce-plugin`が非推奨になり、このリリースで削除された。`kotlin2js`の代わりに`org.jetbrains.kotlin.js`プラグインを使うこと。Kotlin/JS Gradleプラグインが[適切に構成](https://kotlinlang.org/docs/javascript-dce.html)されているとき、デッドコードの削除(Dead code elimination DCE)は動作する。
Kotlin 1.6.0で、`KotlinGradleSubplugin`の非推奨レベルが`ERROR`に変更された。開発者は、コンパイラプラグインを書くためにこのクラスを使っていた。今回のリリースで[このクラスは削除された](https://youtrack.jetbrains.com/issue/KT-48831/)。`KotlinCompilerPluginSupportPlugin`クラスを代わりに使うこと。

::: note
ベストプラクティスは、プロジェクト全体を通して、Kotlinプラグインを1.7.0以上で使うことである。
:::

### 非推奨のコルーチンDSLオプションとプロパティの削除
非推奨の`kotlin.experimental.coroutines` Gradle DSLオプションと、`gradle.properties`で使われていた`kotlin.coroutines`プロパティが削除された。今では、単に[suspend関数](https://kotlinlang.org/docs/coroutines-basics.html#extract-function-refactoring)を使うか、自分のビルドスクリプトで、[`kotlinx.coroutines`依存性を追加する](https://kotlinlang.org/docs/gradle.html#set-a-dependency-on-a-kotlinx-library)だけである。
[コルーチンガイド](https://kotlinlang.org/docs/coroutines-guide.html)で、コルーチンについての知識を深める。
### ツールチェーン拡張メソッド内の型キャストの削除
Kotlin 1.7.0より前は、Kotlin DSLをともにGradleツールチェーンを構成するとき、`JavaToolchainSpec`への型キャストが必要だった。
```Kotlin
kotlin {
    jvmToolchain {
        (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)
    }
}
```
現在は、`(this as JavaToolchainSpec)`部分を省略することができる。
```Kotlin
kotlin {
    jvmToolchain {
        languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)
    }
}
```
# Kotlin 1.7.0への移行
## Kotlin 1.7.0のインストール
IntelliJ IDEA 2022.1とAndroid Studio Chipmunk (212)では、自動的にKotlinプラグインを1.7.0にアップデートする提案がされる。

::: note
Intellij IDEA 2022.2とAndroid Studio Dolphin (213)あるいは、Android Studio Electric Eel (221)用に、今後のIntellij IDEAとAndroid Studiosの更新とともにKotlinプラグイン1.7.0が提供されるだろう。
:::

新しいコマンドラインコンパイラが[GitHubリリースページ](https://github.com/JetBrains/kotlin/releases/tag/v1.7.0)で利用可能である。
## 既存の移行、あるいはKotlin 1.7.0でのプロジェクトの開始
- 既存のプロジェクトをKotlin 1.7.0に移行するには、Kotlinバージョンを`1.7.0`に変更し、GradleあるいはMavenプロジェクトを再インポートする。[Kotlin 1.7.0に更新する方法を理解する](https://kotlinlang.org/docs/releases.html#update-to-a-new-release)。
- 新しいプロジェクトをKotlin 1.7.0で開始するには、Kotlinプラグインを更新し、プロジェクトウィザードを**ファイル-新規-プロジェクト**から実行する。
## Kotlin 1.7.0のための互換性ガイド
Kotlin 1.7.0は[機能リリース](https://kotlinlang.org/docs/kotlin-evolution.html#feature-releases-and-incremental-releases)であり、そのため言語の以前のバージョンのために書かれたコードと互換性が無い変更がもたらされている。そのような変更の詳細な一覧が、[Kotlin 1.7.0のための互換性ガイド](https://kotlinlang.org/docs/compatibility-guide-17.html)に存在する。