メインコンテンツまでスキップ

Kotlin Symbol Processing API

Kotlin Symbol Processing(KSP)は、軽量なコンパイラプラグインを開発するために使用できるAPIです。 KSPは、Kotlinの能力を活用しつつ、学習のハードルを最小限に抑えた、簡素化されたコンパイラプラグインAPIを提供します。 kaptと比較して、KSPを使用するアノテーションプロセッサは最大2倍高速に実行できます。

概要

KSP APIは、Kotlinプログラムを慣用的に処理します。KSPは、拡張関数、宣言場所の変性、ローカル関数など、Kotlin固有の機能を理解しています。また、型を明示的にモデル化し、同値性や代入互換性などの基本的な型チェックを提供します。

このAPIは、Kotlin grammarに従って、シンボルレベルでKotlinプログラムの構造をモデル化します。 KSPベースのプラグインがソースプログラムを処理する場合、クラス、クラスメンバ、関数、および関連するパラメータなどの構成要素にプロセッサからアクセスできますが、ifブロックやforループなどの要素にはアクセスできません。

概念的には、KSPはKotlinリフレクションのKTypeに似ています。 このAPIを使用すると、プロセッサは、特定の型引数を持つクラス宣言から対応する型へ、またはその逆方向にナビゲートできます。 また、型引数の置換、変性の指定、スタープロジェクションの適用、型のNull許容のマークも可能です。

KSPはKotlinプログラムのプリプロセッサフレームワークと考えることもできます。KSPベースのプラグインを_シンボルプロセッサ_、または単に_プロセッサ_と考えると、コンパイルにおけるデータフローは次のステップで説明できます。

  1. プロセッサは、ソースプログラムとリソースを読み取り、分析します。
  2. プロセッサは、コードまたはその他の形式の出力を生成します。
  3. Kotlinコンパイラは、ソースプログラムを生成されたコードとともにコンパイルします。

本格的なコンパイラプラグインとは異なり、プロセッサはコードを変更できません。 言語セマンティクスを変更するコンパイラプラグインは、非常に紛らわしい場合があります。 KSPは、ソースプログラムを読み取り専用として扱うことで、それを回避します。

KSPの概要については、次のビデオをご覧ください。

KSPによるソースファイルの表示方法

ほとんどのプロセッサは、入力ソースコードのさまざまなプログラム構造をナビゲートします。 APIの使用方法に入る前に、KSPの視点から見たファイルがどのように見えるかを見てみましょう。

KSFile
packageName: KSName
fileName: String
annotations: List<KSAnnotation> (File annotations)
declarations: List<KSDeclaration>
KSClassDeclaration // class, interface, object
simpleName: KSName
qualifiedName: KSName
containingFile: String
typeParameters: KSTypeParameter
parentDeclaration: KSDeclaration
classKind: ClassKind
primaryConstructor: KSFunctionDeclaration
superTypes: List<KSTypeReference>
// contains inner classes, member functions, properties, etc.
declarations: List<KSDeclaration>
KSFunctionDeclaration // top level function
simpleName: KSName
qualifiedName: KSName
containingFile: String
typeParameters: KSTypeParameter
parentDeclaration: KSDeclaration
functionKind: FunctionKind
extensionReceiver: KSTypeReference?
returnType: KSTypeReference
parameters: List<KSValueParameter>
// contains local classes, local functions, local variables, etc.
declarations: List<KSDeclaration>
KSPropertyDeclaration // global variable
simpleName: KSName
qualifiedName: KSName
containingFile: String
typeParameters: KSTypeParameter
parentDeclaration: KSDeclaration
extensionReceiver: KSTypeReference?
type: KSTypeReference
getter: KSPropertyGetter
returnType: KSTypeReference
setter: KSPropertySetter
parameter: KSValueParameter

このビューは、ファイル内で宣言されている一般的なもの(クラス、関数、プロパティなど)をリストします。

SymbolProcessorProvider:エントリポイント

KSPは、SymbolProcessorをインスタンス化するために、SymbolProcessorProviderインターフェースの実装を必要とします。

interface SymbolProcessorProvider {
fun create(environment: SymbolProcessorEnvironment): SymbolProcessor
}

SymbolProcessorは次のように定義されます。

interface SymbolProcessor {
fun process(resolver: Resolver): List<KSAnnotated> // Let's focus on this
fun finish() {}
fun onError() {}
}

Resolverは、SymbolProcessorにシンボルなどのコンパイラ詳細へのアクセスを提供します。 トップレベル関数とトップレベルクラスの非ローカル関数をすべて検索するプロセッサは、次のようになります。

class HelloFunctionFinderProcessor : SymbolProcessor() {
// ...
val functions = mutableListOf<KSClassDeclaration>()
val visitor = FindFunctionsVisitor()

override fun process(resolver: Resolver) {
resolver.getAllFiles().forEach { it.accept(visitor, Unit) }
}

inner class FindFunctionsVisitor : KSVisitorVoid() {
override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {
classDeclaration.getDeclaredFunctions().forEach { it.accept(this, Unit) }
}

override fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: Unit) {
functions.add(function)
}

override fun visitFile(file: KSFile, data: Unit) {
file.declarations.forEach { it.accept(this, Unit) }
}
}
// ...

class Provider : SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor = TODO()
}
}

リソース

サポートされているライブラリ

次の表は、Android上の一般的なライブラリと、KSPのさまざまなサポート段階を示しています。

ライブラリステータス
Room公式サポート
Moshi公式サポート
RxHttp公式サポート
Kotshi公式サポート
Lyricist公式サポート
Lich SavedState公式サポート
gRPC Dekorator公式サポート
EasyAdapter公式サポート
Koin Annotations公式サポート
Glide公式サポート
Micronaut公式サポート
Epoxy公式サポート
Paris公式サポート
Auto Dagger公式サポート
SealedX公式サポート
Ktorfit公式サポート
Mockative公式サポート
DeeplinkDispatchairbnb/DeepLinkDispatch#323経由でサポート
DaggerAlpha
MotifAlpha
Hilt開発中
Auto Factoryまだサポートされていません