※ソース記事はこちら
※Kotlin/JS、Kotlin/Nativeについては割愛します。
Kotlin 1.7.0がリリースされた。新しいKotlin/JVMのK2コンパイラのアルファバージョンが明らかになり、言語機能が安定化され、JVM、JS、Nativeプラットフォームのための性能改善がもたらされている。
こちらにこのバージョンの主な更新の一覧がある。
- 現在、新しいKotlin K2コンパイラがアルファであり、それにより重大な性能改善が提供されている。それはJVMのみで利用可能であり、kaptを含めどのコンパイラプラグインとも連携しない。
- Gradleでの差分コンパイルの新しい取り組み。差分コンパイルは、今ではKotlinでない独立したモジュール内で起きた変更もサポートしており、Gradleと互換性がある。
- オプトインが必要なアノテーション、明らかな非null型、ビルダーインターフェイスが安定化された。
- 型引数のためのアンダースコア演算子が今では存在する。他の型が指定されると、自動的に引数の型が推論されるときに使用することができる。
- このリリースではインラインクラスのインライン値に対するdelegateによる実装ができるようになった。今では多くのケースでメモリを割り当てない軽量なラッパーを作ることができる。
このビデオで変更の短い概要を見ることができる。
JVMのための新しいKotlin K2コンパイラがアルファ
今回のKotlinリリースでは、新しいKotlin K2コンパイラのアルファバージョンが導入されている。新しいコンパイラは新しい言語機能の開発を加速し、Kotlinがサポートするすべてのプラットフォームを統一し、性能を改善し、コンパイラ拡張のためにAPI提供することを目的としている。
新しいコンパイラのいくつかの詳しい説明とその利点がすでに公開されている。
注目すべきは、新しいK2コンパイラのアルファバージョンでは、主に性能改善にフォーカスされており、JVMプロジェクトとのみ連携するということが重要である。Kotlin/JS、Kotlin/Native、その他のマルチプラットフォームプロジェクトはサポートされず、kaptを含むコンパイラプラグインのどれとも動作しない。
ベンチマークでは、内部のプロジェクトにおいて、並外れた結果を示している。
プロジェクト | 現在の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 |
KLOC/s性能値は、コンパイラが秒間に処理する千行の数を意味する。
自分のJVMプロジェクトについて性能増加を調べ、古いコンパイラの結果と比較することができる。Kotlin K2コンパイラを有効にするには、次のコンパイラオプションを使うこと。
-Xuse-k2
さらに、K2コンパイラは多くのバグフィックスを含んでいる。この一覧から、オープン状態の問題でさえ、K2では実は修正されていることに注意してほしい。
次のKotlinのリリースではK2コンパイラの安定性が向上し、多くの機能が提供される予定であるので、期待していただき、フィードバックを提供いただきたい。
言語
Kotlin 1.7.0では、delegateによる実装と、型引数のための新しいアンダースコア演算子が導入されている。以前のリリースでプレビューとして導入されたいくつかの言語機能も安定化されている。
インラインクラスのインライン値へのdelegateによる実装
値あるいはクラスインスタンスに対する軽量なラッパーを作りたいとき、手動ですべてのインターフェイスメソッドを実装する必要がある。delegateによる実装により、この問題が解決するが、1.7.0より前では、インラインクラスとは連携しなかった。この制限は削除され、今では多くのケースでメモリを割り当てずに軽量なラッパーを作ることができる。
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では型引数のためのアンダースコア_
演算子が導入されている。他の型が指定されると、自動的に型引数を推論させるために使うことができる。
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)
}
アンダースコア演算子は型引数を推論するための変数リストのどの位置でもを使うことができる。
ビルダー推論の安定化
ビルダー推論とは、ジェネリックなビルダー関数を呼ぶときに役立つ、ある特別な種類の型推論である。これは、コンパイラが関数呼び出しの型引数を推論するのを助ける。型推論には、その関数が引数で受け取るラムダ式内部での別の関数呼び出しの型情報が用いられる。
1.7.0から、1.6.0で導入された、-Xenable-builder-inference
コンパイラオプションを指定しなくても、通常の型推論では型についての十分な情報が得られない場合は自動で有効化される。
カスタムジェネリクスビルダーの書き方を学ぶ
オプトイン必要物の安定化
オプトイン必要物は、今ではStableであり、追加のコンパイラ構成は必要ない。
1.7.0より前は、オプトイン機能自体は、警告を避けるため、-opt-in=kotlin.RequiresOptIn
引数が必要だった。もはやこれは必要ないが、モジュールレベルの他のアノテーションのため、opt-in
コンパイラ引数はまだ使うことができる。
明らかな非null型の安定化
Kotlin 1.7.0では明らかな非null型はStableに昇格になった。これはジェネリクス型のJavaクラスとインターフェイスを拡張するときに、より相互運用性を提供する。
ジェネリクスの型パラメータを使う側で、T & Any
という新しい文法で、明らかな非nullとしてマークをつけることができる。構文の型はインターセクション型のための表記法に由来しており、現在は、&
の左側のnullableな上方境界と、右側の非nullなAny
を持つ型パラメータに限定されている。
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で明らかな非null型についての知識を深める
Kotlin/JVM
今回のリリースでは、Kotlin/JVMコンパイラと新しいコンパイラオプションのための性能改善がもたらされている。さらに関数型インターフェイスのコンストラクタに対する関数参照がStableになっている。留意すべきは、1.7.0からKotlin/JVMのコンパイルのデフォルトバージョンが現在1.8
だということである。
コンパイラ性能の最適化
Kotlin 1.7.0ではKotlin/JVMコンパイラのための性能改善が導入されている。ベンチマークによると、コンパイル時間はKotlin 1.6.0に比較して平均で10%削減された。例えばkotlinx.html
を使うプロジェクトのようにインライン関数を多用するプロジェクトでは、バイトコードの後処理の改善のおかげでコンパイルが早くなるだろう。
新しいコンパイラオプション:-Xjdk-release
Kotlin 1.7.0では-Xjdk-release
新しいコンパイラオプションが提供されている。このオプションはjavacの
コマンドラインオプション--release
に似ている。-Xjdk-release
オプションはターゲットのバイトコードバージョンを制御し、指定したJavaバージョンに対するクラスパスでのJDKのAPIを制限する。例えば、依存性の中のJDKがバージョン9以上であっても、kotlinc -Xjdk-release=1.8
は、Java.lang.Module
を参照することは許可されない。
このオプションはOpenJDKディストリビューションでのみ動作する。
どうかフィードバックをこnYou Trackチケットで残してもらいたい。
関数型インターフェイスのコンストラクタに対する関数参照の安定化
関数型インターフェイスのコンストラクタに対する関数参照は、現在Stableである。コンストラクタ関数をもつインターフェイスから、関数参照を使う関数型インターフェイスへの移行方法を学ぶことができる。
どうか何か問題をみつけたら、You Trackで報告していただきたい。
JVMターゲットバージョン1.6の削除
Kotlin/JVMコンパイルのデフォルトターゲットバージョンは、1.8
である。1.6
ターゲットは削除された。
どうかJVMターゲットバージョンを1.8かそれ以上に移行していただきたい。JVMターゲットバージョンを更新する方法を次で学ぶことができる。
標準ライブラリ
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()
関数は、今では厳密にコレクション要素を返却するか、例外をスローする。
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で導入され、現在Stableである。それらにより、正規表現がString
かCharSequence
内で特定の位置でちょうどマッチしたかどうかをチェックする方法が提供される。
matchesAt()
はマッチのチェックをし、booleanの結果を返却する。
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
を返却する。
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問題でフィードバックをいただければありがたい。
以前の言語とAPIバージョンの延長サポート
幅広い以前のKotlinバージョンで消費する予定のライブラリを開発しているライブラリ開発者をサポートするため、メジャーなKotlinリリースの頻度増加に対応するため、以前の言語とAPIバージョンのためのサポートを延長した。
Kotlin 1.7.0では、2ではなく3つ前の言語とAPIバージョンがサポートされている。これはKotlin 1.7.0では1.4.0までのKotlinバージョンをターゲットにするライブラリの開発をサポートすることを意味する。後方互換性についてのより情報を得るには、Compatibilityモードを参照のこと。
リフレクション経由でのアノテーションへのアクセス
KAnnotatedElement.findAnnotations()
拡張関数は、最初に1.6.0で導入されたが、現在はStableである。このリフレクション関数は、個別に適用されたものと、繰り返しアノテーションを含む、要素についての与えられた型のすべてのアノテーションを返却する。
@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から、実験的機能として利用可能で、Kotlin 1.7.0で今ではStableである。DeepRecursiveFunction
を使うことで、実際の呼び出しスタックを使う代わりに、ヒープ上のスタックを保持する関数を定義することができる。これにより、非常に深い再帰的な演算を実行することが可能になる。深い再帰的な関数を呼び出すには、それをInvoke
する。
この例では、深い再帰的な関数はが、二分木の深さを計算するために使われている。このサンプル関数は、たとえ自分自身を再帰的に100,000回呼び出したとしても、StackOverFlow
がスローされることはない。
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
インスタンスのためにラッパークラスを割り当てない。特に、ホットパスの一部であるコード断片を計測するとき、これにより、計測の性能上のインパクトを最小化してくれる。
@OptIn(ExperimentalTime::class)
fun main() {
val mark = TimeSource.Monotonic.markNow() // 返却される`TimeMark`はインラインクラス
val elapsedDuration = mark.elapsedNow()
}
この最適化は、TimeMark
が取得される元のタイムソースが、TimeSource.Monotonic
として静的に知られるときのみ、利用可能である。
JavaのOptionalのための新しい実験的関数
Kotlin 1.7.0では、JavaのOptional
クラスとの連携を簡単にする、新しい便利な関数が登場している。これらの新しい関数により、JVM上でオプショナルなオブジェクトをアンラップ、変換するために使うことができ、Java APIとより簡潔に連携することができる。
getOrNull()
、getOrDefault()
、getOrElse()
拡張関数により、もし存在する場合、Optional
の値を取り出すことができる。それ以外は、デフォルト値、null
、関数により返却される値がそれぞれ得られる。
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
の値をすでに存在する対象のコレクションに追加する。
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でOptional
拡張関数についてより学ぶことができる。いつも通り、Kotlin issue trackerでフィードバックを歓迎している。
Gradle
このリリースでは、新しいビルドレポート、Gradleプラグインバリアントのサポート、kaptにおける新しい統計などが、導入されている。
差分コンパイルの新しいアプローチ
差分コンパイルの新しいアプローチは、Experimentalである。それはいつでも削除され、変更されるかもしれない。オプトインが必要(詳細は後述)である。評価目的でのみ使用することをおすすめし、You Trackでのフィードバックをいただければありがたい。
Kotlin 1.7.0では、モジュールをまたがった変更のための差分コンパイルが、作り直された。今では差分コンパイルは、依存するKotlinではないモジュール内部の変更でもサポートされ、コンパイルを避けるための、Gradleビルドキャッシュのサポートとの互換性も改善された。
ビルドキャッシュを使うか、非KotlinのGradleモジュールを頻繁に変更する場合に新しいアプローチの最も重大な利点が実感できると考えている。kotlin-gradle-plugin
モジュール上でのKotlinのためのテストでは、キャッシュヒットの後で変更のため、80%以上の改善が見られた。
新しいアプローチを試すには、gradle.properties
に次のオプションをセットすること。
kotlin.incremental.useClasspathSnapshot=true
差分コンパイルについての新しいアプローチは、現在GradleビルドシステムにおけるJVMバックエンドでのみ利用可能である。
計画では、この技術を安定化させ、他のバックエンド(例えばJS)とビルドシステム用のサポートを追加することである。このコンパイルの仕組みでの問題や、おかしなふるまいがあれば、You Trackで報告をいただけると幸いである。
Kotlinチームは、Ivan Gavrilovic、Hung Nguyen、Cédric Champeau、その他外部の貢献者の助けに大変感謝している。
Kotlinコンパイラタスクのためのビルドレポート
Kotlinビルドレポートは、Experimentalである。それはいつでも削除され、変更されるかもしれない。オプトインが必要(詳細は後述)である。評価目的でのみ使用することをおすすめし、You Trackでのフィードバックをいただければありがたい。
Kotlin 1.7.0ではコンパイル性能を追跡するのに役立つビルドレポートが導入されている。レポートには、異なるコンパイルフェーズの時間と、コンパイルが差分にできなかった理由が含まれる。
ビルドレポートはコンパイルタスクの問題を調査したいときに役に立つ。例えば。
- Gradleビルドが長い時間かかり、ひどい性能の根本原因を理解したいとき。
- 同じプロジェクトでのコンパイル時間が異なる、あるときは数秒かかり、ある時は数分かかるとき。
ビルドレポートを有効にするには、gradle.properties
内でビルドレポートの出力先を宣言する。
kotlin.build.report.output=file
次の値(とその組み合わせ)が可能である。
-
file
はローカルファイルにビルドレポートを保存する -
build_scan
は、build scanのカスタム値
セクションにビルドレポートを保存する。
Gradle Enterprise プラグインではカスタム値の数とその長さが制限されている。大きなプロジェクトではいくつかの値は失われることがありうる。
-
http
はHTTP(S)を使ってビルドレポートをPOSTする。POSTメソッドはJSON形式でメトリクスを送信する。データはバージョンごとに異なるかもしれない。Kotlinリポジトリに送信されるデータの現在のバージョンを見ることができる。
長時間動作するコンパイルのためビルドレポートを分析することで解決できる、二つの一般的なケースがある。
- ビルドが差分でなかった。原因を分析し、潜在的な問題を解決すること。
- ビルドは差分だったが、時間がかかりすぎた。ソースファイルを再編成することを試みること。大きなファイルを分割したり、異なるファイルにクラスを分割して保存したり、大きなクラスをリファクタリングしたり、異なるファイルにトップレベル関数を宣言したり等々。
自分のインフラでビルドレポートを自由に使ってかまわない。もしフィードバックがあるか、何か問題にぶつかるか、改善を提案したい場合は、どうか躊躇なくissue trackerに報告していただきたい。
最低サポートバージョンのバージョンアップ
Kotlin 1.7.0から、最低のサポートGradleバージョンは6.7.1である。Gradleプラグインバリアントと新しいGradle APIをサポートするためにバージョンを上げる必要があった。将来は、Gradleプラグインバリアントの恩恵により、最低サポートバージョンを頻繁に上げる必要はなくなるはずである。
さらにAndroid Gradleプラグインの最低サポートバージョンも現在は、3.6.4である。
Gradleプラグインバリアントのサポート
Gradle 7.0ではGradleプラグイン著者のための新しい機能、バリアントつきプラグインが導入された。この機能は、7.1より低いGradleバージョンの互換性を維持しつつ、新しいGradleの機能を簡単にサポートすることが可能である。Gradleでのバリアント選択について知識を深める。
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
ログレベルを有効にしてUsing Kotlin Gradle plugin
から始まる出力文字列、例えばUsing Kotlin Gradle plugin main variant
、を検索する。
こちらにGradleにおけるバリアント選択でいくつかの既知の問題の回避策がある。
このYou Trackチケットでフィードバックを残していただきたい。
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チケットでKotlinBasePlugin
についてのフィードバックを残すことができる。
- Android Gradleプラグイン内でKotlinコンパイルを構成するために、そのための下地を置いた。それは自分のビルドにKotlin Android Gradleプラグインを追加する必要がないという意味である。追加されたサポートを学び試すため、Android Gradleプラグインのリリースアナウンスをフォローしてもらいたい。
sam-with-receiverプラグインがプラグインAPI経由で利用可能
sam-with-receiverプラグインが現在、GradleプラグインDSLで利用可能である。
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チケットでフィードバックを残していただきたい。
kaptにおけるそれぞれのアノテーションプロセッサで生成されたファイルの統計
kotlin-kapt
Gradleプラグインは、すでにそれぞれのプロセッサ用に性能統計をレポートしている。Kotlin 1.7.0から、それぞれのアノテーションプロセッサ用の生成ファイル数についての統計をレポートすることができる。
これはビルドの一部として不要なアノテーションプロセッサがあるかどうかを追跡するのに役に立つ。生成されたレポートを使い、不要なアノテーションプロセッサを引き起こしているモジュールを探して、それを防ぐためにモジュールを更新することができる。
次の2ステップで統計を有効にする。
-
build.gradle.kts
内でshowProcessorStats
フラグをtrue
にセットする。
kapt {
showProcessorStats = true
}
-
gradle.properties
内でkapt.verbose
Graleプロパティをtrue
にセットする。
kapt.verbose=true
コマンドラインオプションverbose
経由でも冗長出力を有効にすることができる。
統計はログに、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チケットでフィードバックを残していただきたい。
kotlin.compiler.execution.strategyシステムプロパティが非推奨
Korlin 1.6.20でKotlinコンパイラの実行戦略を定義するための新しいプロパティが導入された。Kotlin 1.7.0では新しプロパティのために古いkotlin.compiler.execution.strategy
システムプロパティの非推奨サイクルが開始された。
kotlin.compiler.execution.strategy
システムプロパティを使うと、警告を受けるだろう。このプロパティは将来のリリースで削除されるだろう。古いふるまいを保持するには、システムプロパティを同じ名前のGradleプロパティで置き換えること。gradle.properties
でこれを行うことができる。例えば、
kotlin.compiler.execution.strategy=out-of-process
コンパイルタスクプロパティcompilerExecutionStrategy
でも使うことができる。Graldeのページでこれについて知識を深める。
非推奨オプション、メソッド、プラグインの削除
useExperimentalAnnotationメソッドの削除
Kotlin 1.7.0では、useExperimentalAnnotation
Gradleメソッドの非推奨サイクルを完了した。モジュール内でAPIを使用するためにオプトインにするには、optIn()
を使用すること。
例えば、もしGradleモジュールがマルチプラットフォームの場合
sourceSets {
all {
languageSettings.optIn("org.mylibrary.OptInAnnotation")
}
}
Kotlinにおけるオプトイン要求について知識を深める。
非推奨のコンパイルオプションの削除
いくつかのコンパイルオプションの非推奨サイクルが完了した。
-
kotlinOptions.jdkHome
コンパイルオプションが1.5.30で非推奨になり、現在のリリースで削除された。Gradleビルドは現在、このオプションが含まれる場合、失敗する。Javaのツールチェーンの使用を推奨しており、Kotlin 1.5.30からサポートされている。 - 非推奨の
noStdlib
コンパイルオプションも削除された。GradleプラグインはKotlin標準ライブラリが存在するかどうかを制御するために、kotlin.stdlib.default.dependency=true
プロパティを使用している。
コンパイル引数の-jdkHome
と-no-stdlib
はまだ利用可能である。
非推奨プラグインの削除
Kotlin 1.4.0で、kotlin2js
、kotlin-dce-plugin
が非推奨になり、このリリースで削除された。kotlin2js
の代わりにorg.jetbrains.kotlin.js
プラグインを使うこと。Kotlin/JS Gradleプラグインが適切に構成されているとき、デッドコードの削除(Dead code elimination DCE)は動作する。
Kotlin 1.6.0で、KotlinGradleSubplugin
の非推奨レベルがERROR
に変更された。開発者は、コンパイラプラグインを書くためにこのクラスを使っていた。今回のリリースでこのクラスは削除された。KotlinCompilerPluginSupportPlugin
クラスを代わりに使うこと。
ベストプラクティスは、プロジェクト全体を通して、Kotlinプラグインを1.7.0以上で使うことである。
非推奨のコルーチンDSLオプションとプロパティの削除
非推奨のkotlin.experimental.coroutines
Gradle DSLオプションと、gradle.properties
で使われていたkotlin.coroutines
プロパティが削除された。今では、単にsuspend関数を使うか、自分のビルドスクリプトで、kotlinx.coroutines
依存性を追加するだけである。
コルーチンガイドで、コルーチンについての知識を深める。
ツールチェーン拡張メソッド内の型キャストの削除
Kotlin 1.7.0より前は、Kotlin DSLをともにGradleツールチェーンを構成するとき、JavaToolchainSpec
への型キャストが必要だった。
kotlin {
jvmToolchain {
(this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)
}
}
現在は、(this as JavaToolchainSpec)
部分を省略することができる。
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にアップデートする提案がされる。
Intellij IDEA 2022.2とAndroid Studio Dolphin (213)あるいは、Android Studio Electric Eel (221)用に、今後のIntellij IDEAとAndroid Studiosの更新とともにKotlinプラグイン1.7.0が提供されるだろう。
新しいコマンドラインコンパイラがGitHubリリースページで利用可能である。
既存の移行、あるいはKotlin 1.7.0でのプロジェクトの開始
- 既存のプロジェクトをKotlin 1.7.0に移行するには、Kotlinバージョンを
1.7.0
に変更し、GradleあるいはMavenプロジェクトを再インポートする。Kotlin 1.7.0に更新する方法を理解する。 - 新しいプロジェクトをKotlin 1.7.0で開始するには、Kotlinプラグインを更新し、プロジェクトウィザードをファイル-新規-プロジェクトから実行する。
Kotlin 1.7.0のための互換性ガイド
Kotlin 1.7.0は機能リリースであり、そのため言語の以前のバージョンのために書かれたコードと互換性が無い変更がもたらされている。そのような変更の詳細な一覧が、Kotlin 1.7.0のための互換性ガイドに存在する。