Kotlin 1.3.40リリース - JetBrainsブログ概訳

元記事：https://blog.jetbrains.com/kotlin/2019/06/kotlin-1-3-40-released/
とりあえず速報な感じの適当訳なので間違い多数だと思われる
抜けは大体意図的(あくまで概要なので)
無許可なので問題があれば消す

# Kotlin 1.3.40リリース
このバージョンの主な点は以下の通り

- Kotlin/JSのためにNPM, Yarn, WebpackをGradleでサポート
- テストランナーがMPP向けに改善
- 新しい型推論
- Kotlin/Nativeのパフォーマンスと相互運用性の向上

以下では、詳細について述べる。
# STDLibでの試験的な関数の追加
Common:
byte/charの配列をUTF-8でencode/decodeするための関数

- `ByteArray.decodeToString`と`String.encodeToByteArray`
- `CharArray.decodeToString`と`String.encodeToCharArray`
- 
JVM:
`Locale`オブジェクトを引数に取る`capitalize`関数

# JVMにおける、Reified型パラメーターへのリフレクションによるアクセス
新しいリフレクション関数である、`typeOf`が追加される。これは、型パラメーターのクラスの`KType`インスタンスを返す。
使用例

```kotlin
val intType: KType = typeOf<Int>()
println(String::length.returnType == intType) // true
```

この関数の真価は、reified型パラメーターに対しても用いることができることにある。
使用例

```kotlin
@UseExperimental(ExperimentalStdlibApi::class)
inline fun <reified T> accessReifiedTypeArg() {
    val kType = typeOf<T>()
    println(kType.toString())
}

fun main() {
    accessReifiedTypeArg<String>() // kotlin.String
    accessReifiedTypeArg<List<String>>() // kotlin.collections.List<kotlin.String>
}
```

現在、`typeOf`はKotlin/JVMのみで使用可能。しかし、将来的には類似した関数がKotlin/JSやKotlin/Nativeにも追加される予定。

# trimIndentとtrimMerginの最適化
文字列リテラルに対する`trimIndent`と`trimMergin`がコンパイル時に評価されるようになった。
条件として、レシーバーと引数が全て文字列リテラルである必要がある。`"$x"`の様に、変数を内部で使用している場合はこの最適化は行われない。

また、`minBy`と`maxBy`関数にも最適化が加えられている。これは、元となるコレクションの要素がただ1つであった時、引数の`selector`関数は実行されない、というものだ。`selector`が副作用を持っており、それに依存している場合は注意が必要である。

# IntelliJ IDEAでの外部アノテーションの利用
[JavaでのNullabilityに関する外部アノテーション](https://www.jetbrains.com/help/idea/external-annotations.html)を使用している場合、IntelliJがKotlinでそれらを利用する際に警告を出してくれるようになる。
Javaのライブラリを利用しての開発の際に役立つだろう。
注意すべきは、外部アノテーション機能は純粋なIDEの機能であり、これを用いていてもコンパイラーは一切の警告を出さないということだ。Kotlinコンパイラーは依然としてアノテーションの付与されていないJavaの型は全てプラットフォーム型として処理する。

# 新しい型推論アルゴリズム
現在、型推論アルゴリズムの改善に対し継続的に働きかけている。
これにより、多数の重箱の隅のような様々な問題が修正された。
[修正された問題の一覧はこちら](https://youtrack.jetbrains.com/issues?q=%23fixed-in-new-inference%20)
将来的なバージョンでは、新しいアルゴリズムが現在のものを置き換えてデフォルトになる。
新しいアルゴリズムに切り替えた時の後方互換性は非常に重要である。
そのため、このバージョンではフィードバックを得るためにIDE**のみ**でデフォルトで切り替えられる。
そのため、IDEでは正常に動くが、コンパイラーでは未だにサポートされていないような、型推論に関する複雑な重箱の隅のような問題があるということに注意すべきだ。
もし、コンパイルは通るがIDEで赤字の警告表示がされるような挙動を見つけた場合、[新しいIssueを作成](https://youtrack.jetbrains.com/newissue?project=kt)して開発チームに報告して欲しい。
この新しいモードがプロジェクトにおいて正常に動作しないのなら、設定画面の`Build, Execution, Deployment | Compiler | Kotlin Compiler `タブの`Enable new type inference algorithm for IDE analysis`チェックボックスを外すことでオフにできる。

# マルチプラットフォームプロジェクト(MPP)
Kotlin/NativeとKotlin/JSのためのテストランナーはGradle Test runnnerのAPIを全て実装し、Kotlin/JVMのテストランナーと同様に動作するようになった。
テスト失敗のレポートがソースコードナビゲーションとともにコンソールに出力されるようになる。
Gradleによって生成されるテストレポートも同様だ。
テスト対象のフィルタリング用のパラメーターも、標準のGradleのパラメーターを通してサポートされる。
例えば、`--tests some.test.ClassName`

また、Kotlin/JVM, Kotlin/Native, Kotlin/JSの全てのターゲットで実行されたテストの情報を含んだテストレポートをGradleから生成することもできる。

# Kotlin/JS
Kotlin/JSの差分コンパイルのパフォーマンスが向上。大きなプロジェクト/モジュールでは、最大30%のビルド速度向上を達成。
Kotlin/JSの最も大きな目に見える変化は、ツール側である。
Kotlin/JSのプラグインがアップデートされ、`org.jetbrains.kotlin.js`に改名され、[Gradle plugin portal](https://plugins.gradle.org/plugin/org.jetbrains.kotlin.js)で利用できる。
使用するには、`plugins {}`構文を使う。

```
plugins {
    id("org.jetbrains.kotlin.js") version "1.3.40"
}
```
もしくは、Gradle Kotlin DSLを使用している場合、`kotlin`関数を使用することもできる。

```
plugins {
    kotlin("js") version "1.3.40"
}
```

開発チームは、[kotlin-frontend-plugin](https://github.com/Kotlin/kotlin-frontend-plugin)の全ての機能がKotlin/JDとKotlin/Multiplatformのプラグインに移植すべく動いている。一部の機能は既に試験的に含まれている。移植が終われば、`kotlin-frontend-plugin`は廃止する予定だ。

## NPMとWebpackの試験的サポート
Kotlin/JSとKotlin/MultiplatformのGradleプラグインに、Node.js, NPM, Yarn, Webpackを用いた開発を容易にするための試験的機能をいくつか追加した。
それらのプラグインは一時的な`package.json`を生成し、[Yarn](https://yarnpkg.com/en/)を自動ダウンロードし、NPM依存と`node_modules`の管理のために使用する。
Webpackは全ての依存を結合し、ブラウザーフレンドリーなスクリプトを生成するのに使われる。
それらのプラグインは、自動的に`node_modules`フォルダーを管理するためにGradleで宣言されたKotlin/JSの全ての依存を参照する。
JSソースセット用の`dependencies`句内に新しく追加された`npm`関数を用いることにより、NPM依存の追加がサポートされた。
例

```
dependencies {
    implementation(npm("react", "16.8.3"))
}
```
[Yarn Workspaces](https://yarnpkg.com/lang/en/docs/workspaces/)が[Multi-Project Gradle Build](https://guides.gradle.org/creating-multi-project-builds/)のために利用される。
ワークスペースはサブプロジェクトごとに作成され、ルートプロジェクトのbuildディレクトリに構成される。
これにより、Yarnによる`node_modules`のコピーの削減が可能になる。

## Node.jsとブラウザーモード
JSを実行することとテストすることは、常に環境に依存する。
そのため、Node.jsとブラウザーにおける実行環境が新たにサポートされた。
`nodejs {}`や`browser {}`を用いることで、Kotlin/JSやKotlin/MultiplatformのGradle Pluginでtargetを設定できる。

```
kotlin {
    //use js() for a multiplatform project
    target {
        nodejs()
        browser()
    }

    sourceSets["main"].dependencies {
        implementation(kotlin("stdlib-js"))
        implementation(npm("react", "16.8.3"))
    }
}
```
それらのプラグインは、yarnを通じて、全てのNPM依存モジュールをダウンロードする。これには、Karmaを使ったテストをするためのヘッドレスブラウザーを含む
MochaというテストフレームワークがNode.js環境でのテスト実行に利用される。テストランナーはGradleと統合され、Kotlin/JVMのテストで利用可能なものと同様の機能が実装されている。
また、エラーからコードを追いかけるのが難しい時もあるため、JavaScript source mapsをGradleプラグインでの全てのタスクでサポートするようになった。
また、容易に異なるブラウザーでのテストを実行できる。
以下のDSLがGradleで使用可能である。

```
kotlin {
    //use js() for multiplatform project
    target {
        browser {
            testTask {
                useKarma {
                    useIe()
                    useSafari()
                    useFirefox()
                    useChrome()
                    useChromeCanary()
                    useChromeHeadless()
                    usePhantomJS()
                    useOpera()
                }
            }
        }
    }
}
```

Kotlin/JSのコードをNode.jsやブラウザーで動かすための`run`タスクが追加される。
新しいKotlin/JSのビルド機能はまだ試験的であり、現在はmacOSとLinuxのみをサポートし、Windowsではサポートされていないということに注意。

# Kotlin/Native
Kotlin/Native製のアプリケーションのパフォーマンス改善のため、メモリマネージャーに改良が加えられた。
開発チームによるベンチマークでは、ほぼ2倍にパフォーマンスが向上している。
Linux向けにARM x64アーキテクチャがサポートされた。
`CoreLocation`フレームワークがmacOSでは最初から含まれ、事前インポートされている。
Kotlin/Nativeのロギングとエラーメッセージの改善が行われた。

マルチスレッドと非同期処理を扱うのを助けるため、`FreezableAtomicReference`クラスが試験的にKotlin/Nativeに追加された。これはたとえ凍結されていようがなかろうが、`AtomicReference`と同様に振る舞う。

`kotlin-platform-native`は非推奨になった。`kotlin-multiplatform`プラグインに移行するべし。
移行ガイドやその他の情報は[このドキュメント](https://github.com/JetBrains/kotlin-native/blob/master/GRADLE_PLUGIN.md)を参照。

また、`kotlin-multiplatform`プラグインのKotlin/Nativeターゲット設定用のAPIのうち、以前に非推奨設定されていたものを消去した。1.3.40からは、`compilations.outputKinds`はもはやサポートされないので、`binaries`APIを変わりに使用して欲しい。

## Interop
(ここよく分かってないので訳が怪しい。KotlinとObj-C/Swiftの関係が逆になってる可能性あり)
Kotlin/Native製フレームワークのためのジェネリクスの試験的サポートが追加された。これは、Obj-C/Swiftのための型情報をKotlin/Nativeの型パラメーターを持つクラスに追加する。この機能はデフォルトでは無効化されている。有効化するには、コマンドライン引数に`-Xobjc-generics`を追加するか、Gradleに以下の設定を追記する。

```
kotlin {
    iosX64 {
        binaries {
            framework {
                freeCompilerArgs.add("-Xobjc-generics")
            }
        }
    }
}
```

加えて、Kotlinの`Unit`型は生成されたフレームワークでは`Void`型に変換される。
[生成されるメソッド名](https://github.com/JetBrains/kotlin-native/pull/2914)を改良したことにより、Kotlin/Nativeのメソッド名がObjective-Cのものと衝突しなくなった。Objective-Cの可変長引数の関数のinteropが[サポートされた](https://github.com/JetBrains/kotlin-native/pull/2896)。
Cのinteropで、Nullableな文字列が[サポートされた](https://github.com/JetBrains/kotlin-native/issues/2956)。Custom exception hookに関する[問題](https://github.com/JetBrains/kotlin-native/issues/2941)が修正された。
`setUnhandledExceptionHook {}`を使うことで、処理されていないKotlinの例外をキャッチすることができる。

## Kotlin/Nativeにおけるテスト
Kotlin/Nativeのテスト対象に、個別のバイナリー種別が追加された。
実行可能なネイティブテストを作成することが容易になった。

```
kotlin.macosX64 {
    binaries {
        test("integration") {
            /* configuration if needed */
        }
    }
}
```

Kotlin/NativeのテストランナーはGradleと統合され、Kotlin/JVMのテストど類似した機能が実装されている。
例えば、コンソールでのテスト失敗の表示・テストレポートの生成・Gradleのコマンドラインによるテストフィルター等だ。
Gradle APIの`binaries.getTest`関数を使用することで、テストのバイナリーがより容易に手に入るようになった。旧来の実行可能なテストを見つける方法(例えば、`binaries.getExecutable("test", "DEBUG"))`)は動かなくなるので、新しいAPI(`binaries.getTest("DEBUG")`)を代わりに使ってほしい。