Написание первого SymbolProcessor
Реализуйте процессор KSP, который ищет аннотированные классы и записывает их в журнал.
«Написание первого SymbolProcessor» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.
Структура проекта
Процессор KSP находится в отдельном модуле Gradle, например :processor. Модуль-потребитель применяет плагин KSP и объявляет зависимость ksp от модуля процессора. Сам модуль процессора имеет обычную зависимость implementation от API KSP.
Добавление зависимостей KSP
В модуле процессора откройте файл build.gradle.kts:
plugins { kotlin("jvm") }
dependencies {
implementation("com.google.devtools.ksp:symbol-processing-api:2.0.0-1.0.21")
}Интерфейс SymbolProcessor
Реализуйте SymbolProcessor. Основная точка входа — process(resolver: Resolver): List. Верните символы, которые не удалось обработать, например символы, зависимости которых еще не разрешены, чтобы обработать их в следующем раунде.
import com.google.devtools.ksp.processing.*
import com.google.devtools.ksp.symbol.*
class MyProcessor(private val logger: KSPLogger,
private val codeGenerator: CodeGenerator) : SymbolProcessor {
override fun process(resolver: Resolver): List<KSAnnotated> {
val symbols = resolver.getSymbolsWithAnnotation("com.example.MyAnnotation")
// process symbols here
return emptyList()
}
}Поставщик SymbolProcessor
KSP обнаруживает ваш процессор через SymbolProcessorProvider. Зарегистрируйте его в resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider:
class MyProcessorProvider : SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor =
MyProcessor(
logger = environment.logger,
codeGenerator = environment.codeGenerator
)
}Файл регистрации службы
Создайте файл по точному пути в ресурсах модуля процессора:
- Путь:
src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider - Содержимое: полное имя класса
SymbolProcessorProviderс указанием пакета
Поиск символов по аннотации
Используйте resolver.getSymbolsWithAnnotation(fqn), чтобы получить все объявления с вашей аннотацией. Отфильтруйте их по ожидаемому типу объявления, например по объявлениям классов:
val classes = resolver
.getSymbolsWithAnnotation("com.example.MyAnnotation")
.filterIsInstance<KSClassDeclaration>()Проверка символов
Перед обработкой убедитесь, что каждый символ можно полностью разрешить. Символ, ссылки на типы которого еще не скомпилированы, недействителен. Верните такие символы из process(), чтобы повторить попытку в следующем раунде:
val (valid, deferred) = classes.partition { it.validate() }
// process valid; return deferredОбход объявления класса
Используйте шаблон посетителя KSVisitorVoid для обхода структуры класса. Переопределите visitClassDeclaration, чтобы получить доступ к свойствам, функциям и вложенным классам:
class MyVisitor : KSVisitorVoid() {
override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {
val name = classDeclaration.simpleName.asString()
val props = classDeclaration.getAllProperties().toList()
println("Class: $name, props: ${props.size}")
}
}Запись сообщений из процессора
Используйте KSPLogger, чтобы выводить сообщения с разными уровнями важности. logger.error() прерывает сборку; logger.warn() выводит предупреждение; logger.info() выводит информационное сообщение, доступное с параметром --info.
logger.info("Processing class: ${classDeclaration.simpleName.asString()}")
logger.error("Missing required annotation", classDeclaration)Доступ к аннотациям символа
Каждый KSDeclaration содержит последовательность annotations. Используйте filter и arguments, чтобы прочитать значения аннотаций:
val ann = classDeclaration.annotations
.first { it.shortName.asString() == "MyAnnotation" }
val value = ann.arguments.first { it.name?.asString() == "value" }.value as StringПодсказки для инкрементальной обработки
Сообщите KSP, какие выходные файлы зависят от каких входных символов, связав их через CodeGenerator.createNewFile(dependencies = ...). Это позволяет KSP пропускать запуск процессора, если ни один из его входных данных не изменился.
Быстрая проверка
Как KSP обнаруживает вашу реализацию SymbolProcessorProvider?
Итоги: написание первого SymbolProcessor
Основные выводы:
- Реализуйте
SymbolProcessorиSymbolProcessorProviderв отдельном модуле - Зарегистрируйте поставщик через
META-INF/services/ - Используйте
resolver.getSymbolsWithAnnotation(), чтобы находить аннотированные символы - Проверяйте символы перед обработкой; возвращайте неразрешенные символы для повторной попытки
- Используйте
KSPLoggerдля сообщений во время сборки, аCodeGenerator— для записи файлов
Часто задаваемые вопросы
Урок «Написание первого SymbolProcessor» бесплатный?
Да — полный текст урока «Написание первого SymbolProcessor» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.
Чему я научусь в уроке «Написание первого SymbolProcessor»?
Реализуйте процессор KSP, который ищет аннотированные классы и записывает их в журнал. Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Kotlin Academy?
Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Написание первого SymbolProcessor»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Kotlin Academy?
Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- KSP и KAPT: почему KSP быстрее
- Написание первого SymbolProcessor
- Генерация исходных файлов Kotlin с KotlinPoet
- Интеграция процессоров KSP в сборку Gradle