0Pricing
Kotlin Academy · Урок

Написание первого 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 — локальная установка не требуется.

Все уроки этого курса

  1. KSP и KAPT: почему KSP быстрее
  2. Написание первого SymbolProcessor
  3. Генерация исходных файлов Kotlin с KotlinPoet
  4. Интеграция процессоров KSP в сборку Gradle
← Назад к Kotlin Academy