API обработки символов Kotlin
Обработка символов Kotlin (KSP) — это платформа генерации исходного кода для Kotlin. С помощью API KSP можно создавать процессоры, генерирующие код на основе аннотаций в исходном коде.
Цель KSP — упростить создание облегчённых плагинов компилятора. Чётко определённый API скрывает изменения компилятора, поэтому для поддержки процессоров не требуется прилагать много усилий. Однако у этого подхода есть свои компромиссы. Например, процессоры на основе KSP не могут анализировать выражения или операторы и не могут изменять исходный код.
Типичные сценарии использования плагинов на основе KSP:
О том, как создать свой первый процессор на основе KSP, читайте в кратком руководстве по KSP.
Обзор
API KSP обрабатывает программы Kotlin в соответствии с идиомами языка. KSP поддерживает особенности Kotlin, такие как функции-расширения, вариантность на месте объявления и локальные функции. API также явно моделирует типы и предоставляет базовую проверку типов, например проверку эквивалентности и совместимости при присваивании.
API моделирует структуры программ Kotlin на уровне символов в соответствии с грамматикой Kotlin. При обработке исходных программ плагины на основе KSP предоставляют процессорам доступ к таким конструкциям, как классы, члены классов, функции и связанные с ними параметры, но не к таким элементам, как блоки if и циклы for.
Концептуально KSP похож на KType в рефлексии Kotlin. API позволяет процессорам переходить от объявлений классов к соответствующим типам с определёнными аргументами типа и обратно. Также можно подставлять аргументы типа, задавать вариантность, применять проекции со звёздочкой и указывать, допускают ли типы значение null.
Ещё один способ представить KSP — как платформу предварительной обработки программ Kotlin. Если рассматривать плагины на основе KSP как процессоры символов, или просто процессоры, поток данных при компиляции можно описать следующими шагами:
Процессоры считывают и анализируют исходные программы и ресурсы.
Процессоры генерируют код или другие виды выходных данных.
Компилятор 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: точка входа
Для создания SymbolProcessor KSP требует реализации интерфейса 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<KSFunctionDeclaration>()
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 |
|
Kotest |
|
DeeplinkDispatch |
|
Dagger |
|
Motif |
|
Hilt |
|
Auto Factory |
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/ksp-overview.html