Skip to content

Kotlin 1.4.20 の新機能

リリース日: 2020年11月23日

Kotlin 1.4.20では、多数の新しい実験的機能が提供され、1.4.0で追加された機能を含む既存の機能に対する修正と改善が行われています。

新機能の詳細と多くの例については、こちらのブログ記事も参照してください。

Kotlin/JVM

Kotlin/JVMの改善は、最新のJavaバージョンの機能に対応することを目的としています。

Java 15ターゲット

Java 15がKotlin/JVMのターゲットとして利用可能になりました。

invokedynamic文字列結合

invokedynamic文字列結合は実験的機能です。将来的に削除または変更される可能性があります。利用にはオプトインが必要です(詳細は以下を参照)。評価目的でのみ使用してください。この機能に関するフィードバックはYouTrackまでお寄せください。

Kotlin 1.4.20では、文字列結合をJVM 9+ターゲット上で動的呼び出しにコンパイルできるようになり、パフォーマンスが向上します。

現在、この機能は実験的であり、以下のケースをカバーしています。

  • 演算子形式 (a + b)、明示的な形式 (a.plus(b))、および参照形式 ((a::plus)(b)) での String.plus
  • インラインクラスとデータクラスのtoString
  • 単一の非定数引数を持つもの以外の文字列テンプレート(KT-42457を参照)。

invokedynamic文字列結合を有効にするには、以下のいずれかの値とともに-Xstring-concatコンパイラオプションを追加します。

Kotlin/JS

Kotlin/JSは急速に進化を続けており、1.4.20では多くの実験的機能と改善が導入されています。

Gradle DSLの変更

Kotlin/JS用のGradle DSLには、プロジェクトのセットアップとカスタマイズを簡素化する多数の更新が加えられています。これには、webpackの設定調整、自動生成されるpackage.jsonファイルの変更、および推移的な依存関係の制御の改善が含まれます。

webpack設定の一元化

browserターゲット用の新しい設定ブロックcommonWebpackConfigが利用できるようになりました。このブロック内で、webpackTaskrunTasktestTaskの構成を重複させる必要なく、共通の設定を一元的に調整できます。

これら3つのタスクすべてでCSSサポートをデフォルトで有効にするには、プロジェクトのbuild.gradle(.kts)に以下のスニペットを追加します。

groovy
browser {
    commonWebpackConfig {
        cssSupport.enabled = true
    }
    binaries.executable()
}

webpackバンドルの設定の詳細については、こちらを参照してください。

Gradleからのpackage.jsonカスタマイズ

Kotlin/JSのパッケージ管理と配布をより詳細に制御するために、Gradle DSLを介してプロジェクトファイルpackage.jsonにプロパティを追加できるようになりました。

package.jsonにカスタムフィールドを追加するには、コンパイルのpackageJsonブロックでcustomField関数を使用します。

kotlin
kotlin {
    js(BOTH) {
        compilations["main"].packageJson {
            customField("hello", mapOf("one" to 1, "two" to 2))
        }
    }
}

package.jsonのカスタマイズの詳細については、こちらを参照してください。

Yarnの選択的依存関係解決

Yarnの選択的依存関係解決のサポートは実験的機能です。将来的に削除または変更される可能性があります。評価目的でのみ使用してください。この機能に関するフィードバックはYouTrackまでお寄せください。

Kotlin 1.4.20では、Yarnの選択的依存関係解決を設定する方法を提供します。これは、依存するパッケージの依存関係をオーバーライドするメカニズムです。

GradleのYarnPlugin内のYarnRootExtensionを通じてこれを使用できます。プロジェクトのパッケージの解決バージョンに影響を与えるには、パッケージ名セレクタ(Yarnで指定されている)と解決すべきバージョンをresolution関数に渡します。

kotlin
rootProject.plugins.withType<YarnPlugin> {
    rootProject.the<YarnRootExtension>().apply {
        resolution("react", "16.0.0")
        resolution("processor/decamelize", "3.0.0")
    }
}

ここでは、reactを必要とするすべてのnpm依存関係がバージョン16.0.0を受け取り、processorはその依存関係decamelizeをバージョン3.0.0として受け取ります。

粒度の粗いワークスペースの無効化

粒度の粗いワークスペースの無効化は実験的機能です。将来的に削除または変更される可能性があります。評価目的でのみ使用してください。この機能に関するフィードバックはYouTrackまでお寄せください。

ビルド時間を短縮するため、Kotlin/JS Gradleプラグインは、特定のGradleタスクに必要な依存関係のみをインストールします。たとえば、webpack-dev-serverパッケージは、*Runタスクのいずれかを実行するときにのみインストールされ、assembleタスクの実行時にはインストールされません。このような動作は、複数のGradleプロセスを並行して実行する際に問題を引き起こす可能性があります。依存関係の要件が衝突すると、npmパッケージの2つのインストールがエラーの原因となることがあります。

この問題を解決するため、Kotlin 1.4.20には、これらのいわゆる_粒度の粗いワークスペース_を無効にするオプションが含まれています。この機能は現在、GradleのYarnPlugin内のYarnRootExtensionを通じて利用できます。使用するには、build.gradle.ktsファイルに以下のスニペットを追加します。

kotlin
rootProject.plugins.withType<YarnPlugin> {
    rootProject.the<YarnRootExtension>().disableGranularWorkspaces()
}

新しいウィザードテンプレート

プロジェクト作成時により便利にプロジェクトをカスタマイズできるよう、KotlinのプロジェクトウィザードにはKotlin/JSアプリケーション用の新しいテンプレートが追加されました。

  • ブラウザアプリケーション - ブラウザで実行される最小限のKotlin/JS Gradleプロジェクト。
  • Reactアプリケーション - 適切なkotlin-wrappersを使用するReactアプリ。スタイルシート、ナビゲーションコンポーネント、または状態コンテナの統合を有効にするオプションを提供します。
  • Node.jsアプリケーション - Node.jsランタイムで実行するための最小限のプロジェクト。実験的なkotlinx-nodejsパッケージを直接含めるオプションが付属しています。

IRコンパイラでのコンパイルエラーの無視

_コンパイルエラー無視_モードは実験的機能です。将来的に削除または変更される可能性があります。利用にはオプトインが必要です(詳細は以下を参照)。評価目的でのみ使用してください。この機能に関するフィードバックはYouTrackまでお寄せください。

Kotlin/JS用のIRコンパイラには、新しい実験的なモードである_エラーを伴うコンパイル_が導入されました。このモードでは、コードにエラーが含まれていても実行できます。たとえば、アプリケーション全体がまだ準備できていない段階で特定の機能を試したい場合などに便利です。

このモードには2つの許容ポリシーがあります。

  • SEMANTIC: コンパイラは、val x: String = 3のように、構文的には正しいが意味的に正しくないコードを受け入れます。
  • SYNTAX: コンパイラは、構文エラーが含まれていても任意のコードを受け入れます。

エラーを伴うコンパイルを許可するには、上記のいずれかの値とともに-Xerror-tolerance-policy=コンパイラオプションを追加します。

Kotlin/JS IRコンパイラの詳細については、こちらを参照してください。

Kotlin/Native

Kotlin/Nativeの1.4.20における優先事項は、パフォーマンスと既存機能の磨き上げです。注目すべき改善点は以下のとおりです。

エスケープ解析

エスケープ解析メカニズムは実験的機能です。将来的に削除または変更される可能性があります。評価目的でのみ使用してください。この機能に関するフィードバックはYouTrackまでお寄せください。

Kotlin/Nativeには、新しいエスケープ解析メカニズムのプロトタイプが導入されました。これにより、特定のオブジェクトをヒープではなくスタックに割り当てることで、ランタイムパフォーマンスが向上します。このメカニズムは、当社のベンチマークで平均10%のパフォーマンス向上を示しており、プログラムをさらに高速化するために引き続き改善を進めています。

エスケープ解析は、リリースビルド(-optコンパイラオプションを使用)の場合、個別のコンパイルフェーズで実行されます。

エスケープ解析フェーズを無効にしたい場合は、-Xdisable-phases=EscapeAnalysisコンパイラオプションを使用します。

パフォーマンスの改善とバグ修正

Kotlin/Nativeでは、1.4.0で追加されたコード共有メカニズムを含む、さまざまなコンポーネントでパフォーマンスの改善とバグ修正が行われています。

Objective-C例外のオプトインによるラッピング

Objective-C例外ラッピングメカニズムは実験的機能です。将来的に削除または変更される可能性があります。利用にはオプトインが必要です(詳細は以下を参照)。評価目的でのみ使用してください。この機能に関するフィードバックはYouTrackまでお寄せください。

Kotlin/Nativeは、Objective-Cコードからスローされた例外をランタイムで処理し、プログラムのクラッシュを回避できるようになりました。

NSExceptionForeignException型のKotlin例外にラップするようにオプトインできます。これにより、元のNSExceptionへの参照が保持され、根本原因に関する情報を取得し、適切に処理できるようになります。

Objective-C例外のラッピングを有効にするには、cinterop呼び出しで-Xforeign-exception-mode objc-wrapオプションを指定するか、.defファイルにforeignExceptionMode = objc-wrapプロパティを追加します。CocoaPods統合を使用している場合は、依存関係のpod {}ビルドスクリプトブロックで次のようにオプションを指定します。

kotlin
pod("foo") {
    extraOpts = listOf("-Xforeign-exception-mode", "objc-wrap")
}

デフォルトの動作は変更されていません。Objective-Cコードから例外がスローされると、プログラムは終了します。

CocoaPodsプラグインの改善

Kotlin 1.4.20では、CocoaPods統合の改善が継続されています。具体的には、以下の新機能を試すことができます。

タスク実行の改善

CocoaPodsプラグインは、タスク実行フローが改善されました。たとえば、新しいCocoaPods依存関係を追加しても、既存の依存関係は再ビルドされません。追加のターゲットを追加しても、既存の依存関係の再ビルドには影響しません。

拡張されたDSL

KotlinプロジェクトにCocoaPods依存関係を追加するためのDSLに、新しい機能が追加されました。

ローカルのPodとCocoaPodsリポジトリのPodに加えて、以下の種類のライブラリへの依存関係を追加できます。

  • カスタムスペックリポジトリからのライブラリ。
  • Gitリポジトリからのリモートライブラリ。
  • アーカイブからのライブラリ(任意のHTTPアドレスでも利用可能)。
  • 静的ライブラリ。
  • カスタムcinteropオプションを持つライブラリ。

KotlinプロジェクトでのCocoaPods依存関係の追加の詳細については、こちらを参照してください。Kotlin with CocoaPodsサンプルで例を見つけることができます。

Xcodeとの統合の更新

Xcodeと正しく連携するには、KotlinでPodfileをいくつか変更する必要があります。

  • Kotlin PodがGit、HTTP、またはspecRepo Podの依存関係を持っている場合、それもPodfileに指定する必要があります。
  • カスタムスペックからライブラリを追加する場合、Podfileの冒頭でスペックの場所も指定する必要があります。

これにより、統合エラーにはIDEAで詳細な説明が表示されるようになりました。Podfileに問題がある場合、すぐに修正方法がわかります。

Kotlin Podの作成の詳細については、こちらを参照してください。

Xcode 12ライブラリのサポート

Xcode 12に付属する新しいライブラリのサポートを追加しました。Kotlinコードからこれらのライブラリを使用できるようになりました。

Kotlin Multiplatform

マルチプラットフォームライブラリの公開構造の更新

Kotlin 1.4.20以降、個別のメタデータ公開はなくなりました。メタデータアーティファクトは、ライブラリ全体を表す_ルート_公開に含まれるようになり、共通ソースセットへの依存関係として追加されると、適切なプラットフォーム固有のアーティファクトに自動的に解決されます。

マルチプラットフォームライブラリの公開の詳細については、こちらを参照してください。

以前のバージョンとの互換性

この構造変更により、階層型プロジェクト構造を持つプロジェクト間の互換性が損なわれます。マルチプラットフォームプロジェクトとそれが依存するライブラリの両方が階層型プロジェクト構造を持つ場合、両方をKotlin 1.4.20以降に同時に更新する必要があります。Kotlin 1.4.20で公開されたライブラリは、以前のバージョンで公開されたプロジェクトからは使用できません。

階層型プロジェクト構造を持たないプロジェクトとライブラリは互換性を維持します。

標準ライブラリ

Kotlin 1.4.20の標準ライブラリでは、ファイル操作のための新しい拡張機能とパフォーマンスの向上が提供されます。

java.nio.file.Pathの拡張機能

java.nio.file.Pathの拡張機能は実験的機能です。将来的に削除または変更される可能性があります。利用にはオプトインが必要です(詳細は以下を参照)。評価目的でのみ使用してください。これらの機能に関するフィードバックはYouTrackまでお寄せください。

現在、標準ライブラリはjava.nio.file.Pathの実験的な拡張機能を提供しています。現代のJVMファイルAPIをKotlinらしい方法で操作することが、kotlin.ioパッケージのjava.io.File拡張機能を使用するのと同様になりました。

kotlin
// construct path with the div (/) operator
val baseDir = Path("/base")
val subDir = baseDir / "subdirectory" 

// list files in a directory
val kotlinFiles: List<Path> = Path("/home/user").listDirectoryEntries("*.kt")

これらの拡張機能は、kotlin-stdlib-jdk7モジュールのkotlin.io.pathパッケージで利用できます。拡張機能を使用するには、実験的アノテーション@ExperimentalPathApiオプトインする必要があります。

String.replace関数のパフォーマンス向上

String.replace()の新しい実装により、関数の実行が高速化されます。大文字と小文字を区別するバリアントはindexOfに基づく手動置換ループを使用し、大文字と小文字を区別しないバリアントは正規表現マッチングを使用します。

Kotlin Android Extensions

1.4.20では、Kotlin Android Extensionsプラグインが非推奨となり、Parcelable実装ジェネレータは別のプラグインに移動されます。

Synthetic Viewsの非推奨化

_Synthetic views_は、UI要素とのインタラクションを簡素化し、ボイラープレートを削減するために、以前Kotlin Android Extensionsプラグインで導入されました。現在、Googleは同じことを行うネイティブメカニズムであるAndroid Jetpackのビューバインディングを提供しており、私たちはこれらを支持してSynthetic viewsを非推奨にしています。

kotlin-android-extensionsからParcelable実装ジェネレータを抽出し、それ以外の部分(Synthetic views)の非推奨化サイクルを開始します。現時点では、これらは非推奨警告とともに動作し続けます。将来的には、プロジェクトを別のソリューションに切り替える必要があります。AndroidプロジェクトをSynthetic viewsからビューバインディングに移行するのに役立つガイドラインはこちらです。

Parcelable実装ジェネレータ用の新しいプラグイン

Parcelable実装ジェネレータは、新しいkotlin-parcelizeプラグインで利用できるようになりました。kotlin-android-extensionsの代わりにこのプラグインを適用してください。

kotlin-parcelizekotlin-android-extensionsは、1つのモジュールで同時に適用することはできません。

@Parcelizeアノテーションはkotlinx.parcelizeパッケージに移動されました。

Parcelable実装ジェネレータの詳細については、Androidドキュメントを参照してください。